欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

圖解Promise實(shí)現(xiàn)原理(四)——Promise靜態(tài)方法實(shí)現(xiàn)-創(chuàng)新互聯(lián)

本文首發(fā)于 vivo互聯(lián)網(wǎng)技術(shù) 微信公眾號 
鏈接: https://mp.weixin.qq.com/s/Lp_5BXdpm7G29Z7zT_S-bQ
作者:Morrain

成都創(chuàng)新互聯(lián)專注于企業(yè)網(wǎng)絡(luò)營銷推廣、網(wǎng)站重做改版、秀英網(wǎng)站定制設(shè)計(jì)、自適應(yīng)品牌網(wǎng)站建設(shè)、HTML5建站成都商城網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、成都外貿(mào)網(wǎng)站建設(shè)公司、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計(jì)等建站業(yè)務(wù),價格優(yōu)惠性價比高,為秀英等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

了用法,原生提供了Promise對象。更多關(guān)于 Promise 的介紹請參考阮一峰老師的  ES6入門 之 Promise 對象。

很多同學(xué)在學(xué)習(xí) Promise 時,知其然卻不知其所以然,對其中的用法理解不了。 本系列文章由淺入深逐步實(shí)現(xiàn) Promise,并結(jié)合流程圖、實(shí)例以及動畫進(jìn)行演示,達(dá)到深刻理解 Promise 用法的目的。

本系列文章有如下幾個章節(jié)組成:

  1. 圖解 Promise 實(shí)現(xiàn)原理(一)—— 基礎(chǔ)實(shí)現(xiàn)

  2. 圖解 Promise 實(shí)現(xiàn)原理(二)—— Promise 鏈?zhǔn)秸{(diào)用

  3. 圖解 Promise 實(shí)現(xiàn)原理(三)—— Promise 原型方法實(shí)現(xiàn)

  4. 圖解 Promise 實(shí)現(xiàn)原理(四)—— Promise 靜態(tài)方法實(shí)現(xiàn)

一、前言

上一節(jié)中,實(shí)現(xiàn)了 Promise 的原型方法。包括增加異常狀態(tài),catch以及 finally。截至目前,Promise 的實(shí)現(xiàn)如下:

class Promise {
  callbacks = [];
  state = 'pending';//增加狀態(tài)
  value = null;//保存結(jié)果
  constructor(fn) {
    fn(this._resolve.bind(this), this._reject.bind(this));
  }
  then(onFulfilled, onRejected) {
    return new Promise((resolve, reject) => {
      this._handle({
        onFulfilled: onFulfilled || null,
        onRejected: onRejected || null,
        resolve: resolve,
        reject: reject
      });
    });
  }
  catch(onError) {
    return this.then(null, onError);
  }
  finally(onDone) {
    if (typeof onDone !== 'function') return this.then();
 
    let Promise = this.constructor;
    return this.then(
      value => Promise.resolve(onDone()).then(() => value),
      reason => Promise.resolve(onDone()).then(() => { throw reason })
    );
  }
  _handle(callback) {
    if (this.state === 'pending') {
      this.callbacks.push(callback);
      return;
    }
 
    let cb = this.state === 'fulfilled' ? callback.onFulfilled : callback.onRejected;
 
    if (!cb) {//如果then中沒有傳遞任何東西
      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
      cb(this.value);
      return;
    }
 
    let ret;
 
    try {
      ret = cb(this.value);
      cb = this.state === 'fulfilled' ? callback.resolve : callback.reject;
    } catch (error) {
      ret = error;
      cb = callback.reject
    } finally {
      cb(ret);
    }
 
  }
  _resolve(value) {
 
    if (value && (typeof value === 'object' || typeof value === 'function')) {
      var then = value.then;
      if (typeof then === 'function') {
        then.call(value, this._resolve.bind(this), this._reject.bind(this));
        return;
      }
    }
 
    this.state = 'fulfilled';//改變狀態(tài)
    this.value = value;//保存結(jié)果
    this.callbacks.forEach(callback => this._handle(callback));
  }
  _reject(error) {
    this.state = 'rejected';
    this.value = error;
    this.callbacks.forEach(callback => this._handle(callback));
  }
}

接下來再介紹一下 Promise 中靜態(tài)方法的實(shí)現(xiàn),譬如 Promise.resolve、Promise.reject、Promise.all 和 Promise.race。其它靜態(tài)方法的實(shí)現(xiàn)也是類似的。

二、靜態(tài)方法

1、Promise.resolve && Promise.reject

除了前文中提到的 Promise實(shí)例的原型方法外,Promise 還提供了 Promise.resolve 和Promise.reject 方法。用于將非 Promise 實(shí)例包裝為 Promise 實(shí)例。例如:

Promise.resolve('foo')
// 等價于
new Promise(resolve => resolve('foo'))

Promise.resolve 的參數(shù)不同對應(yīng)的處理也不同,如果 Promise.resolve 的參數(shù)是一個 Promise的實(shí)例,那么 Promise.resolve 將不做任何改動,直接返回這個 Promise 實(shí)例,如果是一個基本數(shù)據(jù)類型,譬如上例中的字符串,Promise.resolve 就會新建一個 Promise 實(shí)例返回。這樣當(dāng)我們不清楚拿到的對象到底是不是 Promise 實(shí)例時,為了保證統(tǒng)一的行為,Promise.resolve 就變得很有用了。看一個例子:

const Id2NameMap = {};
const getNameById = function (id) {
 
  if (Id2NameMap[id]) return Id2NameMap[id];
 
  return new Promise(resolve => {
    mockGetNameById(id, function (name) {
      Id2NameMap[id] = name;
      resolve(name);
    })
  });
}
getNameById(id).then(name => {
  console.log(name);
});

上面的場景我們會經(jīng)常碰到,為了減少請求,經(jīng)常會緩存數(shù)據(jù),我們獲取到 id 對應(yīng)的名字后,存到 Id2NameMap 對象里,下次再通過 id 去請求 id 對應(yīng)的 name 時先看 Id2NameMap里有沒有,如果有就直接返回對應(yīng)的 name,如果沒有就發(fā)起異步請求,獲取到后放到 Id2NameMap 中去。

其實(shí)上面的代碼是有問題的,如果命中 Id2NameMap 里的值,getNameById 返回的結(jié)果就是 name,而不是 Promise 實(shí)例。此時 getNameById(id).then 會報錯。在我們不清楚返回的是否是 Promise 實(shí)例的情況下,就可以使用 Promise.resolve 進(jìn)行包裝:

Promise.resolve(getNameById(id)).then(name => {
  console.log(name);
});

這樣一來,不管 getNameById(id) 返回的是什么,邏輯都沒有問題。看下面的Demo:

demo-Promise.resolve 的源碼

在實(shí)現(xiàn) Promise.resolve 之前,我們先看下它的參數(shù)分為哪些情況:

(1)參數(shù)是一個 Promise 實(shí)例

如果參數(shù)是 Promise 實(shí)例,那么 Promise.resolve 將不做任何修改、原封不動地返回這個實(shí)例。

(2)參數(shù)是一個 thenable 對象

thenable 對象指的是具有 then 方法的對象,比如下面這個對象。

let thenable = {
  then: function(onFulfilled) {
    onFulfilled(42);
  }
};[object Object]

Promise.resolve 方法會將這個對象轉(zhuǎn)為 Promise 對象,然后就立即執(zhí)行 thenable 對象的 then方法。

let thenable = {
  then: function(onFulfilled) {
    onFulfilled(42);
  }
};
 
let p1 = Promise.resolve(thenable);
p1.then(function(value) {
  console.log(value);  // 42
});

上面代碼中,thenable對象的then方法執(zhí)行后,對象p1的狀態(tài)就變?yōu)閞esolved,從而立即執(zhí)行最后那個then方法指定的回調(diào)函數(shù),輸出 42。

(3)參數(shù)不是具有 then 方法的對象,或根本就不是對象

如果參數(shù)是一個原始值,或者是一個不具有then方法的對象,則 Promise.resolve 方法返回一個新的 Promise 對象,狀態(tài)為 resolved。

(4)不帶任務(wù)參數(shù)

Promise.resolve 方法允許調(diào)用時不帶參數(shù),直接返回一個 resolved 狀態(tài)的 Promise 對象。

static resolve(value) {
  if (value && value instanceof Promise) {
    return value;
  } else if (value && typeof value === 'object' && typeof value.then === 'function') {
    let then = value.then;
    return new Promise(resolve => {
      then(resolve);
    });
 
 
  } else if (value) {
    return new Promise(resolve => resolve(value));
  } else {
    return new Promise(resolve => resolve());
  }
}
圖解 Promise 實(shí)現(xiàn)原理(四)—— Promise 靜態(tài)方法實(shí)現(xiàn) 圖解 Promise 實(shí)現(xiàn)原理(四)—— Promise 靜態(tài)方法實(shí)現(xiàn)

當(dāng)前文章:圖解Promise實(shí)現(xiàn)原理(四)——Promise靜態(tài)方法實(shí)現(xiàn)-創(chuàng)新互聯(lián)
網(wǎng)址分享:http://www.chinadenli.net/article30/dodppo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護(hù)品牌網(wǎng)站建設(shè)品牌網(wǎng)站制作電子商務(wù)Google面包屑導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站建設(shè)