<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          4 個(gè)JavaScript 中一流函數(shù)的日常用例

          共 5869字,需瀏覽 12分鐘

           ·

          2021-12-24 19:27

          英文 | https://medium.com/codex/4-daily-use-cases-of-first-class-functions-in-javascript-17b7079a6217

          翻譯 | 楊小愛


          每種語言都有使其與眾不同的功能。在這篇文章中,我想提到 JavaScript 中的“一流函數(shù)”特性。這篇文章不是關(guān)于如何使用它的教程。相反,我想指出該功能的一些實(shí)際用途以及它給開發(fā)人員帶來的好處。
          好吧,開始吧!
          什么是“一流函數(shù)”?
          維基百科的定義:
          在計(jì)算機(jī)科學(xué)中,如果一種編程語言將函數(shù)視為一等公民,那么它就被稱為具有一等函數(shù)。這意味著該語言支持將函數(shù)作為參數(shù)傳遞給其他函數(shù),將它們作為其他函數(shù)的值返回,并將它們分配給變量或?qū)⑺鼈兇鎯?chǔ)在數(shù)據(jù)結(jié)構(gòu)中。
          例如,在 JavaScript 中,我們可以將一個(gè)函數(shù)分配給一個(gè)變量。
          var sum = function(a, b) {  return a + b;}var total = sum(10, 1);

          如果我們是第一次閱讀,這個(gè)定義會(huì)有點(diǎn)混亂。然而,事實(shí)是我們?cè)诓恢榈那闆r下使用了它。

          AddEventListener — 學(xué)習(xí) JavaScript 的第一課

          過去,引入 JavaScript 是為了向網(wǎng)站添加動(dòng)態(tài)行為。例如,我們希望在用戶單擊按鈕時(shí)更改文本。當(dāng)有人學(xué)習(xí) JavaScript 時(shí),這是第一行代碼。

          <html>  <body>    <p id="text">The text will change when you click on the button</p>    <button type="button" id="btn">Click me!</button>    <script>      let btn = document.getElementById("btn");      let text = document.getElementById("text");
          btn.addEventListener("click", function() { text.innerHTML = "New text!" });</script> </body></html>

          在第 9 行,我們將函數(shù)作為參數(shù)傳遞給 addEventListener 方法。該功能與按鈕的“單擊”事件相關(guān)聯(lián)。當(dāng)事件被觸發(fā)時(shí),該函數(shù)將運(yùn)行。

          讓我們好奇——第 1 部分

          要了解該功能的作用,讓我們考慮一下它不可用的語言。無論使用何種編程語言,添加動(dòng)態(tài)行為在 UI 開發(fā)中都很常見。如果我們不能將函數(shù)作為參數(shù)傳遞怎么辦?我期待您在留言區(qū)與我們分享您的看法。

          發(fā)送 HTTP 請(qǐng)求——JavaScript 中的常見任務(wù)

          我以Axios為例。它是最流行的用于發(fā)送 HTTP 請(qǐng)求的 JavaScript 庫(kù)之一。在一個(gè)項(xiàng)目中,我們可能需要添加一些常用的配置。

          例如,要將 JWT 發(fā)送到服務(wù)器,我們希望將標(biāo)頭 Authorization 添加到所有請(qǐng)求。因此,我們需要一個(gè)函數(shù)來抓取 JWT 并將其添加到標(biāo)題中。

          可以使用攔截器來完成。

          // Add jwt to all requests using interceptorsaxios.interceptors.request.use(function (config) {
          const jwt = globalStore.getJWT(); // assume the token is saved in a global store. config.headers["Authorization"] = `Bearer ${jwt}`; return config;}, null, { synchronous: true });

          同樣,我們傳遞 2 個(gè)函數(shù)作為 use 方法的參數(shù)。第一個(gè)函數(shù)在請(qǐng)求的標(biāo)頭中設(shè)置令牌。

          如果出現(xiàn)錯(cuò)誤,則第二個(gè)函數(shù)將運(yùn)行(為簡(jiǎn)單起見,我們沒有在此處定義它)。Axios在處理一個(gè)請(qǐng)求時(shí),會(huì)一一運(yùn)行所有的攔截器,將用戶的配置轉(zhuǎn)化為完整配置。

          然后它將請(qǐng)求發(fā)送到服務(wù)器。

          Axios 處理攔截器的方式很好地說明了 JavaScript 中的一流函數(shù)。

          // ------------------------------- inside inteceptor's use method ------------------------//InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {  this.handlers.push({    fulfilled: fulfilled,    rejected: rejected,    synchronous: options ? options.synchronous : false,    runWhen: options ? options.runWhen : null  });  return this.handlers.length - 1;};
          // -------------------------------- process interceptors ---------------------------------//// filter out skipped interceptorsvar requestInterceptorChain = [];var synchronousRequestInterceptors = true;this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { if (typeof interceptor.runWhen === 'function' && interceptor.runWhen(config) === false) { return; }
          synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor.synchronous;
          requestInterceptorChain.unshift(interceptor.fulfilled, interceptor.rejected);});
          // ------------------------------- execute synchronous interceptors ---------------------//var newConfig = config;while (requestInterceptorChain.length) { var onFulfilled = requestInterceptorChain.shift(); var onRejected = requestInterceptorChain.shift(); try { newConfig = onFulfilled(newConfig); } catch (error) { onRejected(error); break; }}

          在第 23 行,我們?cè)?usemethod 中傳遞的已完成和被拒絕的函數(shù)被添加到 requestInterceptorChain。我們將函數(shù)存儲(chǔ)在數(shù)組中。

          然后 Axios 將運(yùn)行它們中的每一個(gè)。在 while 循環(huán)中,您可以看到函數(shù)被分配給要調(diào)用的變量。

          讓我們好奇——第 2 部分

          發(fā)送 HTTP 請(qǐng)求不限于前端開發(fā)。在開發(fā)后端部分時(shí),我們可能需要向外部服務(wù)器發(fā)送請(qǐng)求。您能否向我們解釋一下如何以您的首選語言處理 HTTP 請(qǐng)求配置?歡迎在留言區(qū)分享您的想法。

          在 Node.js 中處理 HTTP 請(qǐng)求

          使用 Node.js,我們可以使用 JavaScript 開發(fā)后端部分。后端開發(fā)是關(guān)于處理 HTTP 請(qǐng)求,即:接收它們,解析它們,找到正確的答案,并響應(yīng)客戶端。Node.js 最常用的框架之一是 Express.js。

          該框架使用中間件來完成上述任務(wù)。以下是 Express 官方頁面中中間件的定義:

          中間件函數(shù)是可以訪問請(qǐng)求對(duì)象 (req)、響應(yīng)對(duì)象 (res) 和應(yīng)用程序請(qǐng)求-響應(yīng)循環(huán)中的下一個(gè)中間件函數(shù)的函數(shù)。

          您可以在下面看到中間件的示例。

          var express = require('express');var app = express();
          app.use('/users', function (req, res, next) {
          // assume only authenticated users can access to /users route if(!req.user) { // non authenticated users res.json({status : "failed", message: "Please login!"}); return; }
          // if users is authenticated, go to the next middleware next();});

          中間件函數(shù)在 use 方法中傳遞。反過來,它接受另一個(gè)函數(shù) next 作為參數(shù)。最后調(diào)用 next 函數(shù),將控制權(quán)傳遞給堆棧中的以下中間件。

          Express 因其簡(jiǎn)單性而廣受歡迎并被廣泛使用。“一個(gè) Express 應(yīng)用程序本質(zhì)上是一系列中間件函數(shù)調(diào)用?!?盡管看起來微不足道,但 Express 的中間件可以幫助我們完成 Web 服務(wù)器的所有任務(wù):記錄請(qǐng)求、壓縮響應(yīng)、設(shè)置 cookie、防止 XSS 攻擊……僅舉幾例。

          讓我們?cè)俅魏闷妫?/span>

          HTTP 請(qǐng)求在其他后端框架中是如何處理的?您能將它與 Express 中間件進(jìn)行比較嗎?每種方法的優(yōu)點(diǎn)/缺點(diǎn)是什么?你看,有很多問題要研究!

          最后但并非最不重要的——JavaScript 中的回調(diào)地獄

          如您所知,JavaScript 是單線程的。但它提供了一種有效的機(jī)制來處理長(zhǎng)時(shí)間運(yùn)行的任務(wù)。我們可以立即開始下一個(gè)任務(wù),而不是等待任務(wù)完成,并定義前一個(gè)任務(wù)完成后我們需要做什么。這就是回調(diào)函數(shù)的來源——定義在長(zhǎng)時(shí)間運(yùn)行的任務(wù)后應(yīng)該運(yùn)行什么。

          import { readFile } from 'fs';
          readFile('/etc/passwd', (err, data) => { if (err) throw err; console.log(data);});

          回調(diào)函數(shù)為我們提供了一個(gè)強(qiáng)大的工具來處理 I/O 綁定的應(yīng)用程序。然而,任何好事如果被濫用都會(huì)變壞。您可以查看下面的示例。

          fs.readdir(source, function (err, files) {  if (err) {    console.log('Error finding files: ' + err)  } else {    files.forEach(function (filename, fileIndex) {      console.log(filename)      gm(source + filename).size(function (err, values) {        if (err) {          console.log('Error identifying file size: ' + err)        } else {          console.log(filename + ' : ' + values)          aspect = (values.width / values.height)          widths.forEach(function (width, widthIndex) {            height = Math.round(width / aspect)            console.log('resizing ' + filename + 'to ' + height + 'x' + height)            this.resize(width, height).write(dest + 'w' + width + '_' + filename, function(err) {              if (err) console.log('Error writing file: ' + err)            })          }.bind(this))        }      })    })  }})

          多個(gè)回調(diào)函數(shù)和 if/else 語句使代碼難以理解。如果我們添加更多邏輯,它在未來可能變得不可維護(hù)。由于這個(gè)問題,引入了更新的功能。Promise 似乎可以幫助我們編寫一個(gè)更簡(jiǎn)潔的程序。Async/await 關(guān)鍵字允許我們編寫看起來像同步代碼的異步代碼。

          總結(jié)

          在這篇文章中,我向您展示了一些在 JavaScript 中使用“一流函數(shù)”的真實(shí)示例。

          我們每天都使用此功能并認(rèn)為這是理所當(dāng)然的。通過這些例子,我希望您能看到這個(gè)特性為我們提供的一些很酷的東西。

          我也給你留下了很多問題。好奇心是幫助我們成長(zhǎng)的特征之一。

          很高興在評(píng)論區(qū)看到您的回答,讓我們互相學(xué)習(xí)。您也可以將文章分享給其他語言的開發(fā)者進(jìn)行討論。

          感謝您的閱讀!


          學(xué)習(xí)更多技能

          請(qǐng)點(diǎn)擊下方公眾號(hào)

          瀏覽 53
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  99色免费视频 | 北条麻妃无码一区二区 | 熟女日逼| 女人被插视频 | www黄色在线观看 |