<del id="lhp53"><delect id="lhp53"><listing id="lhp53"></listing></delect></del>

<noframes id="lhp53"><em id="lhp53"><form id="lhp53"></form></em>

<form id="lhp53"></form>
    <noframes id="lhp53"><address id="lhp53"><nobr id="lhp53"></nobr></address><address id="lhp53"><listing id="lhp53"><nobr id="lhp53"></nobr></listing></address>

    <listing id="lhp53"><nobr id="lhp53"><meter id="lhp53"></meter></nobr></listing><form id="lhp53"></form>

      北海電腦維修站

      北海電腦維修站

      段是向操作系統發出請求北海要求讀取文件

      ECMAScript 6(簡稱ES6)將 JavaScript 異步編程帶入了一個全新的階段。這篇文章的主題北海就是介紹更強大、更完善的 ES6 異步編程方法。

       

      首先我們回顧一下javascript異步的發展歷程。

       

      ES6 以前:

      回調函數(callback):nodejs express 中常用北海ajax中常用。

       

      ES6:

      promise對象:nodejs最早有bluebird promise的雛形北海axios中常用。

      generator函數:nodejs koa框架使用率很高。

       

      ES7:

      async/await語法:當前最常用的異步語法北海nodejs koa2 完全使用該語法。

       

      目錄

      什么是異步

      回調函數callback

      promise對象

      協程

      Generator 函數

      Generator 函數的用法

      async-await

      什么是異步編輯本段回目錄

       

      所謂"異步"北海簡單說就是一個任務分成兩段北海先執行第一段北海然后轉而執行其他任務北海等做好了準備北海再回過頭執行第二段。比如北海有一個任務是讀取文件進行處理北海異步的執行過程就是下面這樣。

      異步

       

      上圖中北海任務的第一段是向操作系統發出請求北海要求讀取文件。然后北海程序執行其他任務北海等到操作系統返回文件北海再接著執行任務的第二段(處理文件)。

       

      這種不連續的執行北海就叫做異步。相應地北海連續的執行北海就叫做同步。

      同步

       

      上圖就是同步的執行方式。由于是連續執行北海不能插入其他任務北海所以操作系統從硬盤讀取文件的這段時間北海程序只能干等著。

       

      回調函數callback編輯本段回目錄

       

      JavaScript 語言對異步編程的實現北海就是回調函數。所謂回調函數北海就是把任務的第二段單獨寫在一個函數里面北海等到重新執行這個任務的時候北海就直接調用這個函數。它的英語名字 callback北海直譯過來就是"重新調用"。

      回調字面也好理解北海就是先處理本體函數北海再處理回調的函數北海舉個例子北海方便大家理解。

       

       

      上面的例子很好理解北海首先執行主體函數A北海打印結果:我是主題函數;

      然后執行回調函數callback 也就是B北海打印結果:我是回調函數。

       

      promise對象編輯本段回目錄

       

      promise 對象用于一個異步操作的最終完成(或最終失敗)及其結果的表示。

      簡單地說就是處理一個異步請求。我們經常會做些斷言北海如果我贏了你就嫁給我北海如果輸了我就嫁給你之類的斷言。

      這就是promise的中文含義:斷言北海一個成功北海一個失敗。

      舉個例子北海方便大家理解:

      promise構造函數的參數是一個函數北海我們把它稱為處理器函數。

      處理器函數接收兩個函數reslove和reject作為其參數北海當異步操作順利執行則執行reslove函數, 當異步操作中發生異常時北海則執行reject函數。

      通過resolve傳入得的值北??梢栽趖hen方法中獲取到北海通過reject傳入的值可以在chatch方法中獲取到。

      因為then和catch都返回一個相同的promise對象北海所以可以進行鏈式調用。

       

      Promise 的寫法只是回調函數的改進北海使用then方法以后北海異步任務的兩段執行看得更清楚了北海除此以外北海并無新意。

      Promise 的最大問題是代碼冗余北海原來的任務被Promise 包裝了一下北海不管什么操作北海一眼看去都是一堆 then北海原來的語義變得很不清楚。

      那么北海有沒有更好的寫法呢?

       

      協程編輯本段回目錄

       

      傳統的編程語言北海早有異步編程的解決方案(其實是多任務的解決方案)。其中有一種叫做"協程"(coroutine)北海意思是多個線程互相協作北海完成異步任務。

      協程有點像函數北海又有點像線程。它的運行流程大致如下。

      第一步北海協程A開始執行。

      第二步北海協程A執行到一半北海進入暫停北海執行權轉移到協程B。

      第三步北海(一段時間后)協程B交還執行權。

      第四步北海協程A恢復執行。

      上面流程的協程A北海就是異步任務北海因為它分成兩段(或多段)執行。

      舉例來說北海讀取文件的協程寫法如下。

       

      1.function asnycJob() { 
      2. // ...其他代碼 
      3. var f = yield readFile(fileA); 
      4. // ...其他代碼 
      5.} 

       

      上面代碼的函數 asyncJob 是一個協程北海它的奧妙就在其中的 yield 命令。它表示執行到此處北海執行權將交給其他協程。也就是說北海yield命令是異步兩個階段的分界線。

      協程遇到 yield 命令就暫停北海等到執行權返回北海再從暫停的地方繼續往后執行。它的最大優點北海就是代碼的寫法非常像同步操作北海如果去除yield命令北海簡直一模一樣。

       

      Generator 函數編輯本段回目錄

      Generator 函數是協程在 ES6 的實現北海最大特點就是可以交出函數的執行權(即暫停執行)。

       

      1.function asnycJob() { 
      2. // ...其他代碼 
      3. var f = yield readFile(fileA); 
      4. // ...其他代碼 5.} 

       

      上面代碼就是一個 Generator 函數。它不同于普通函數北海是可以暫停執行的北海所以函數名之前要加星號北海以示區別。

       

      整個 Generator 函數就是一個封裝的異步任務北?;蛘哒f是異步任務的容器。異步操作需要暫停的地方北海都用 yield 語句注明。Generator 函數的執行方法如下。

       

      1.var g = gen(1); 
      2.g.next() // { value: 3, done: false } 
      3.g.next() // { value: undefined, done: true } 

       

      上面代碼中北海調用 Generator 函數北海會返回一個內部指針(即遍歷器 )g 。這是 Generator 函數不同于普通函數的另一個地方北海即執行它不會返回結果北海返回的是指針對象。調用指針 g 的 next 方法北海會移動內部指針(即執行異步任務的第一段)北海指向第一個遇到的 yield 語句北海上例是執行到 x + 2 為止。

       

      換言之北海next 方法的作用是分階段執行 Generator 函數。每次調用 next 方法北海會返回一個對象北海表示當前階段的信息( value 屬性和 done 屬性)。value 屬性是 yield 語句后面表達式的值北海表示當前階段的值;done 屬性是一個布爾值北海表示 Generator 函數是否執行完畢北海即是否還有下一個階段。

       

      Generator 函數的用法編輯本段回目錄

       

      下面看看如何使用 Generator 函數北海執行一個真實的異步任務。

       

      1.var fetch = require('node-fetch'); 
      2.function* gen(){ 
      3. var url = 'https://api.github.com/users/github'; 
      4. var result = yield fetch(url); 
      5. console.log(result.bio); 
      6.} 

       

      上面代碼中北海Generator 函數封裝了一個異步操作北海該操作先讀取一個遠程接口北海然后從 JSON 格式的數據解析信息。就像前面說過的北海這段代碼非常像同步操作北海除了加上了 yield 命令。

      執行這段代碼的方法如下。

       

      1.var g = gen(); 
      2.var result = g.next(); 
      3.result.value.then(function(data){ 
      4. return data.json(); 
      5.}).then(function(data){ 
      6. g.next(data); 
      7.}); 

       

      上面代碼中北海首先執行 Generator 函數北海獲取遍歷器對象北海然后使用 next 方法(第二行)北海執行異步任務的第一階段。由于 Fetch 模塊返回的是一個 Promise 對象北海因此要用 then 方法調用下一個next 方法。

       

      可以看到北海雖然 Generator 函數將異步操作表示得很簡潔北海但是流程管理卻不方便(即何時執行第一階段、何時執行第二階段)。

       

      async-await編輯本段回目錄

       

      async函數返回一個promise對象北海如果在async函數中返回一個直接量北海async會通過Promise.resolve封裝成Promise對象。

      我們可以通過調用promise對象的then方法北海獲取這個直接量。

       

       

      那如過async函數不返回值北海又會是怎么樣呢?

       

       

      await會暫停當前async的執行北海await會阻塞代碼的執行北海直到await后的表達式處理完成北海代碼才能繼續往下執行。

      await后的表達式既可以是一個Promise對象北海也可以是任何要等待的值。

      如果await等到的是一個 Promise 對象北海await 就忙起來了北海它會阻塞后面的代碼北海等著 Promise 對象 resolve北海然后得到 resolve 的值北海作為 await 表達式的運算結果。

      上邊你看到阻塞一詞北海不要驚慌北海async/await只是一種語法糖北海代碼執行與多個callback嵌套調用沒有區別。

      本質并不是同步代碼北海它只是讓你思考代碼邏輯的時候能夠以同步的思維去思考北海避開回調地獄。

      簡而言之-async/await是以同步的思維去寫異步的代碼北海所以async/await并不會影響node的并發數北海大家可以大膽的應用到項目中去!

      如果它等到的不是一個 Promise 對象北海那 await 表達式的運算結果就是它等到的東西。

      舉個例子北海方便大家理解:

       


      cache
      Processed in 0.005373 Second.
      免费人成在线播放视频 <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <蜘蛛词>| <文本链> <文本链> <文本链> <文本链> <文本链> <文本链>