《你不知道的Javascript--中卷 學習總結》(異步、promise)

異步

一、任什麼時候候,只要把一段代碼包裝成一個函數,並指定它在響應某個事件(定時器、鼠標點 擊、Ajax 響應等)時執行,你就是在代碼中建立了一個未來執行的塊。ajax

二、多數狀況下,代碼在開發者工具的控制檯中輸出的對象表示與指望是一致的。可是, 下面這段代碼運行的時候,瀏覽器可能會認爲須要把控制檯 I/O 延遲到後臺,在這種狀況下, 等到瀏覽器控制檯輸出對象內容時,a.index++ 可能已經執行,所以會顯示 { index: 2 }。數組

var a = {
          index: 1
    };
    // 而後
    console.log( a ); // 2
    // 再而後 
    a.index++;
複製代碼

三、併發交互模式promise

  • 根據返回的特性標識處理,根據不一樣的url來存放在數組的不一樣位置。
var res = [];
    function response(data) {
      if (data.url == "http://some.url.1") {
          res[0] = data;
      }
      else if (data.url == "http://some.url.2") {
          res[1] = data;
    } }
    // ajax(..)是某個庫中提供的某個Ajax函數
    ajax( "http://some.url.1", response );
    ajax( "http://some.url.2", response );
複製代碼
  • 兩個值所有存在,在進行函數調用(門閂)
var a, b;
    function foo(x) {
         a = x * 2;
         if (a && b) {
             baz();
    } }
    function bar(y) {
         b = y * 2;
         if (a && b) {
             baz();
    } }
    function baz() {
        console.log( a + b );
    }
    // ajax(..)是某個庫中的某個Ajax函數 
    ajax( "http://some.url.1", foo ); 
    ajax( "http://some.url.2", bar );

複製代碼
  • 只要其中一個執行
var a;
    function foo(x) {
        if (!a) {
            a = x * 2;
            baz();
        }
    }
    function bar(x) {
        if (!a) {
            a = x / 2;
            baz(); 
        }
    }
    function baz() {
        console.log( a );
    }
    // ajax(..)是某個庫中的某個Ajax函數 
    ajax( "http://some.url.1", foo ); 
    ajax( "http://some.url.2", bar );
複製代碼

Promise

檢測promise類型(檢測是否認義thenable)

if (
         p !== null &&
         (
             typeof p === "object" ||
             typeof p === "function"
    ) &&
    typeof p.then === "function" ){
    // 假定這是一個thenable! }
    else {
    // 不是thenable
    }
複製代碼

Promise API 概述

  • new Promise(..) 構造器

一、有啓示性的構造器 Promise(..) 必須和 new 一塊兒使用,而且必須提供一個函數回調。這個 回調是同步的當即調用的。這個函數接受兩個函數回調,用以支持 promise 的決議。通 常咱們把這兩個函數稱爲resolve(..)reject(..)瀏覽器

var p = new Promise( function(resolve,reject){ 
    // resolve(..)用於決議/完成這個promise
    // reject(..)用於拒絕這個promise
    } );
複製代碼

二、reject(..) 就是拒絕這個 promise;但 resolve(..) 既可能完成 promise,也可能拒絕,要 根據傳入參數而定。若是傳給 resolve(..) 的是一個非 Promise非 thenable 的當即值,這 個 promise 就會用這個值完成bash

三、若是傳給 resolve(..) 的是一個真正的 Promise 或 thenable 值,這個值就會被遞歸展 開,而且(要構造的)promise 將取用其最終決議值或狀態。併發

  • Promise.resolve(..) 和 Promise.reject(..)

一、建立一個已被拒絕的 Promise 的快捷方式是使用 Promise.reject(..),因此如下兩個 promise 是等價的異步

var p1 = new Promise( function(resolve,reject){
         reject( "Oops" );
     } );
     var p2 = Promise.reject( "Oops" );
複製代碼

二、Promise.resolve(..) 會展開 thenable 值(前面已屢次介紹)。在這種狀況 下,返回的 Promise 採用傳入的這個 thenable 的最終決議值,多是完成,也多是拒絕函數

var fulfilledTh = {
        then: function(cb) { cb( 42 ); }
    };
    var rejectedTh = {
        then: function(cb,errCb) {
            errCb( "Oops" );
    } };
     var p1 = Promise.resolve( fulfilledTh );
     var p2 = Promise.resolve( rejectedTh );
    // p1是完成的promise 
    // p2是拒絕的promise
複製代碼

三、若是傳入的是真正的 Promise,Promise.resolve(..) 什麼都不會作,只會直接 把這個值返回工具

  • then(..) 和 catch(..)

一、每一個 Promise 實例(不是 Promise API 命名空間)都有 then(..) 和 catch(..) 方法,經過 這兩個方法能夠爲這個 Promise 註冊完成和拒絕處理函數url

二、then(..) 接受一個或兩個參數:第一個用於完成回調,第二個用於拒絕回調。若是二者中 的任何一個被省略或者做爲非函數值傳入的話,就會替換爲相應的默認回調。默認完成回 調只是把消息傳遞下去,而默認拒絕回調則只是從新拋出(傳播)其接收到的出錯緣由。

三、catch(..) 只接受一個拒絕回調做爲參數,並自動替換默認完成 回調。換句話說,它等價於 then(null,..)

p.then( fulfilled );
    p.then( fulfilled, rejected );
    p.catch( rejected ); // 或者p.then( null, rejected )
複製代碼

四、then(..) 和 catch(..) 也會建立並返回一個新的 promise,這個 promise 能夠用於實現 Promise 鏈式流程控制。若是完成或拒絕回調中拋出異常,返回的 promise 是被拒絕的。如 果任意一個回調返回非 Promise、非 thenable 的當即值,這個值會被用做返回 promise 的完 成值。若是完成處理函數返回一個 promise 或 thenable,那麼這個值會被展開,並做爲返回 promise 的決議值。

  • Promise.all([ .. ]) 和 Promise.race([ .. ])

一、ES6PromiseAPI靜態輔助函數Promise.all([ .. ])和Promise.race([ .. ])都會建立一 個 Promise 做爲它們的返回值。這個 promise 的決議徹底由傳入的 promise 數組控制。

二、對Promise.all([ .. ])來講,只有傳入的全部promise都完成,返回promise才能完成。 若是有任何 promise 被拒絕,返回的主 promise 就當即會被拒絕(拋棄任何其餘 promise 的 結果)。若是完成的話,你會獲得一個數組,其中包含傳入的全部 promise 的完成值。對於 拒絕的狀況,你只會獲得第一個拒絕 promise 的拒絕理由值。

三、對Promise.race([ .. ])來講,只有第一個決議的promise(完成或拒絕)取勝,而且其 決議結果成爲返回 promise 的決議。

var p1 = Promise.resolve( 42 );
     var p2 = Promise.resolve( "Hello World" );
     var p3 = Promise.reject( "Oops" );
     Promise.race( [p1,p2,p3] )
    .then( function(msg){
        console.log( msg );
    } );
    Promise.all( [p1,p2,p3] )
    .catch( function(err){
        console.error( err );
    } );
    Promise.all( [p1,p2] )
    .then( function(msgs){
        console.log( msgs );
    } );
    // 42
    // "Oops"
    // [42,"Hello World"]
複製代碼

四、若向Promise.all([ .. ])傳入空數組,它會當即完成,但Promise. race([ .. ]) 會掛住,且永遠不會決議。

相關文章
相關標籤/搜索