国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Promise原理分析一

WilsonLiu95 / 968人閱讀

摘要:原理分析一對(duì)象用于異步計(jì)算。它有兩個(gè)參數(shù),分別為在成功和失敗情況下的回調(diào)函數(shù)。實(shí)現(xiàn)根據(jù)當(dāng)前狀態(tài)對(duì)回調(diào)函數(shù)進(jìn)行處理,同時(shí)返回一個(gè)新的對(duì)象,以便鏈?zhǔn)秸{(diào)用。,注冊(cè)回調(diào)函數(shù)到當(dāng)前的對(duì)象中或,立即執(zhí)行回調(diào)函數(shù)說(shuō)明方法只處理被拒絕的情況,并返回一個(gè)。

Promise原理分析一

Promise對(duì)象用于異步計(jì)算。一個(gè)Promise對(duì)象代表著一個(gè)還未完成,但預(yù)期將來(lái)會(huì)完成的操作。

Note:

Promise原理分析二

Promise對(duì)象有以下幾種狀態(tài):

pending: 初始狀態(tài), 既不是 fulfilled 也不是 rejected.

fulfilled: 成功的操作.

rejected: 失敗的操作.

pending狀態(tài)的Promise對(duì)象既可轉(zhuǎn)換為帶著一個(gè)成功值的fulfilled狀態(tài),也可變?yōu)閹е粋€(gè)失敗信息的 rejected狀態(tài)。當(dāng)狀態(tài)發(fā)生轉(zhuǎn)換時(shí),Promise.then綁定的方法就會(huì)被調(diào)用。(當(dāng)綁定方法時(shí),如果 Promise對(duì)象已經(jīng)處于fulfilled或rejected狀態(tài),那么相應(yīng)的方法將會(huì)被立刻調(diào)用,所以在異步操作的完成情況和它的綁定方法之間不存在競(jìng)爭(zhēng)條件。)

因?yàn)镻romise.prototype.then和Promise.prototype.catch方法返回Promises對(duì)象, 所以它們可以被鏈?zhǔn)秸{(diào)用。

constructor 說(shuō)明

語(yǔ)法

new Promise(executor);
new Promise(function(resolve, reject) { ... });

參數(shù)

name desc
executor 帶有resolve、reject兩個(gè)參數(shù)的函數(shù)對(duì)象。第一個(gè)參數(shù)用在處理執(zhí)行成功的場(chǎng)景,第二個(gè)參數(shù)則用在處理執(zhí)行失敗的場(chǎng)景。一旦我們的操作完成即可調(diào)用這些函數(shù)。
實(shí)現(xiàn)

構(gòu)造函數(shù)主要完成狀態(tài)的初始化,并提供resolvereject兩個(gè)方法給創(chuàng)建者以轉(zhuǎn)變狀態(tài)。

const utils = require("./utils");
const isFunction = utils.isFunction;

const STATUS = {
  PENDING: "pending",
  FULFILLED: "fulfilled",
  REJECTED: "rejected"
};

const SYMBOL_STATUS = Symbol("status");
const SYMBOL_DATA = Symbol("data");
const SYMBOL_FULFILLED_CALLBACK = Symbol("fulfilledCallback");
const SYMBOL_REJECTED_CALLBACK = Symbol("rejectedCallback");

class Promise {
  constructor(executor) {
    if (!isFunction(executor)) {
      throw Error(`Promise executor ${executor} is not a function`);
    }

    const self = this;
    // 初始狀態(tài)為pending
    const status = self[SYMBOL_STATUS] = STATUS.PENDING;

    // 使用symbol實(shí)現(xiàn)私有化
    self[SYMBOL_FULFILLED_CALLBACK] = undefined;
    self[SYMBOL_REJECTED_CALLBACK] = undefined;
    self[SYMBOL_DATA] = undefined;

    function resovle(value) {
      // todo
    }

    function reject(reason) {
      // todo
    }

    // 執(zhí)行executor函數(shù),若出現(xiàn)異常則調(diào)用reject方法,將狀態(tài)變?yōu)閞ejected,同時(shí)調(diào)用回調(diào)函數(shù)
    try {
      executor(resovle, reject);
    } catch (err) {
      reject(err);
    }
  }
}

上面代碼中完成了構(gòu)造函數(shù)的雛形,而resolvereject兩個(gè)函數(shù)的職責(zé)為狀態(tài)轉(zhuǎn)變和回調(diào)函數(shù)的調(diào)用:

resolve,接受一個(gè)成功值,傳遞給綁定的fulfilled回調(diào)函數(shù)中。主要工作是將當(dāng)前狀態(tài)變?yōu)?b>fulfilled狀態(tài),同時(shí)調(diào)用綁定的fulfilled回調(diào)函數(shù):

function resovle(value) {
  const fulfilledCallback = self[SYMBOL_FULFILLED_CALLBACK];

  if (status === STATUS.PENDING) {
    self[SYMBOL_STATUS] = STATUS.FULFILLED;  // 狀態(tài)轉(zhuǎn)換
    self[SYMBOL_DATA] = value;  // 保存成功值

    if (isFunction(fulfilledCallback)) {
      setTimeout(() => {  // 不阻塞主流程,在下一個(gè)事件輪詢中再調(diào)用fulfilled回調(diào)函數(shù)
        fulfilledCallback(value);
      });
    }
  }
}

reject,接受一個(gè)失敗信息,傳遞給綁定的rejected回調(diào)函數(shù)中。主要工作是將當(dāng)前狀態(tài)變?yōu)?b>rejected 狀態(tài),同時(shí)調(diào)用綁定的rejected回調(diào)函數(shù):

function reject(reason) {
  const rejectedCallback = self[SYMBOL_REJECTED_CALLBACK];

  if (status === STATUS.PENDING) {
    self[SYMBOL_STATUS] = STATUS.REJECTED;  // 狀態(tài)轉(zhuǎn)換
    self[SYMBOL_DATA] = reason;  // 保存成功值

    if (isFunction(rejectedCallback)) {
      setTimeout(() => {  // 不阻塞主流程,在下一個(gè)事件輪詢中再調(diào)用rejected回調(diào)函數(shù)
        rejectedCallback(reason);
      });
    }
  }
}

fulfilled`和rejected回調(diào)函數(shù)是通過(guò)Promise.prototype.then和Promise.prototype.catch注冊(cè)的。

then 說(shuō)明

then方法返回一個(gè)Promise。它有兩個(gè)參數(shù),分別為Promise在成功和失敗情況下的回調(diào)函數(shù)。

語(yǔ)法

p.then(onFulfilled, onRejected);

p.then(function(value) {
  // todo
}, function(reason) {
  // todo
});

參數(shù)

name desc
onFulfilled 一個(gè)函數(shù),當(dāng)Promise的狀態(tài)為fulfilled時(shí)調(diào)用。該函數(shù)有一個(gè)參數(shù),為成功的返回值。
onRejected 一個(gè)函數(shù),當(dāng)Promise的狀態(tài)為rejected時(shí)調(diào)用。該函數(shù)有一個(gè)參數(shù),為失敗的原因。
實(shí)現(xiàn)

根據(jù)當(dāng)前狀態(tài)對(duì)回調(diào)函數(shù)進(jìn)行處理,同時(shí)返回一個(gè)新的Promise對(duì)象,以便鏈?zhǔn)秸{(diào)用。

then(onFulfilled, onRejected) {
  const self = this;
  const status = self[SYMBOL_STATUS];
  const data = self[SYMBOL_DATA];
  const resolveValue = self[SYMBOL_RESOLVE_VALUE];
  // 如果onFulfilled不是函數(shù),回調(diào)函數(shù)僅返回成功值
  const fulfilledCallback = isFunction(onFulfilled)
      ? onFulfilled
      : function returnFunc(value) { return value; };
  // 如果onRejected不是函數(shù),回調(diào)函數(shù)僅返回失敗信息
  const rejectedCallback = isFunction(onRejected)
      ? onRejected
      : function throwFunc(reason) { throw reason; };
      
  // 當(dāng)前狀態(tài)為pending
  if (status === STATUS.PENDING) {
    // 返回一個(gè)新的Promise對(duì)象,可以被鏈?zhǔn)秸{(diào)用
    return new Promise((resolve, reject) => {
      // 將fulfilled回調(diào)函數(shù)注冊(cè)到當(dāng)前Promise對(duì)象中(非新Promise對(duì)象)
      self[SYMBOL_FULFILLED_CALLBACK] = value => {
        // 根據(jù)回調(diào)函數(shù)的執(zhí)行情況,通過(guò)傳遞的新Promise對(duì)象的resolve和reject方法對(duì)其狀態(tài)進(jìn)行轉(zhuǎn)變
        try {
          const newValue = fulfilledCallback(value);
          // 解析成功值
          resolveValue(newValue, resolve, reject);
        } catch (err) {
          reject(err);
        }
      };

      // 同上
      self[SYMBOL_REJECTED_CALLBACK] = reason => {
        try {
          const newReason = rejectedCallback(reason);
          resolveValue(newReason, resolve, reject);
        } catch (err) {
          reject(err);
        }
      };
    });
  }

  // 當(dāng)前狀態(tài)為fulfilled
  if (status === STATUS.FULFILLED) {
    // 返回一個(gè)新的Promise對(duì)象,可以被鏈?zhǔn)秸{(diào)用
    return new Promise((resolve, reject) => {
      // 在下一個(gè)事件輪詢中立即調(diào)用fulfilled回調(diào)函數(shù),根據(jù)執(zhí)行情況決定新Promise對(duì)象的狀態(tài)轉(zhuǎn)變
      setTimeout(() => {
        try {
          const newValue = fulfilledCallback(data);
          resolveValue(newValue, resolve, reject);
        } catch (err) {
          reject(err);
        }
      });
    });
  }

  // 當(dāng)前狀態(tài)為rejected
  if (status === STATUS.REJECTED) {
    // 返回一個(gè)新的Promise對(duì)象,可以被鏈?zhǔn)秸{(diào)用
    return new Promise((resolve, reject) => {
      // 在下一個(gè)事件輪詢中立即調(diào)用rejected回調(diào)函數(shù),根據(jù)執(zhí)行情況決定新Promise對(duì)象的狀態(tài)轉(zhuǎn)變
      setTimeout(() => {
        try {
          const newReason = rejectedCallback(data);
          resolveValue(newReason, resolve, reject);
        } catch (err) {
          reject(err);
        }
      });
    });
  }
}

// 解析傳遞值函數(shù)
[SYMBOL_RESOLVE_VALUE](value, resolve, reject) {
  // 若傳遞值為Promise對(duì)象,將新Promise對(duì)象的resolve和reject傳遞給Promise傳遞值以觸發(fā)狀態(tài)的轉(zhuǎn)換
  if (value instanceof Promise) {
    value.then(resolve, reject);
    return;
  }

  // 若傳遞值不是Promise對(duì)象,傳遞給resolve方法
  resolve(value);
}

根據(jù)當(dāng)前Promise對(duì)象的狀態(tài),對(duì)回調(diào)函數(shù)進(jìn)行注冊(cè)或立即執(zhí)行,同時(shí)返回一個(gè)新的Promise對(duì)象。

pending,注冊(cè)回調(diào)函數(shù)到當(dāng)前的Promise對(duì)象中

fulfilledrejected,立即執(zhí)行回調(diào)函數(shù)

catch 說(shuō)明

catch方法只處理Promise被拒絕的情況,并返回一個(gè)Promise。該方法的行為和調(diào)用Promise.prototype.then(undefined, onRejected)相同。

語(yǔ)法

p.catch(onRejected);

p.catch(function(reason) {
   // todo
});

參數(shù)

name desc
onRejected 當(dāng)Promise被拒絕時(shí)調(diào)用的函數(shù)。該函數(shù)調(diào)用時(shí)會(huì)傳入一個(gè)參數(shù):失敗原因。
實(shí)現(xiàn)

catch方法是對(duì)then方法的包裝,僅傳遞onRejected失敗回調(diào)函數(shù)。

catch(onRejected) {
  return this.then(null, onRejected);
}
總結(jié)

現(xiàn)在回顧下Promise的實(shí)現(xiàn)過(guò)程,其主要使用了設(shè)計(jì)模式中的觀察者模式:

通過(guò)Promise.prototype.then和Promise.prototype.catch方法將觀察者方法注冊(cè)到被觀察者Promise對(duì)象中,同時(shí)返回一個(gè)新的Promise對(duì)象,以便可以鏈?zhǔn)秸{(diào)用。

被觀察者管理內(nèi)部pending、fulfilled和rejected的狀態(tài)轉(zhuǎn)變,同時(shí)通過(guò)構(gòu)造函數(shù)中傳遞的resolve和reject方法以主動(dòng)觸發(fā)狀態(tài)轉(zhuǎn)變和通知觀察者。

關(guān)鍵知識(shí)點(diǎn)

Promise

MDN

symbol

ruanyifeng

觀察者模式

百度百科

資源 完整代碼

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/80384.html

相關(guān)文章

  • Promise原理分析

    摘要:原理分析一說(shuō)明方法返回一個(gè)被拒絕的對(duì)象。實(shí)現(xiàn)創(chuàng)建一個(gè)新的對(duì)象,通過(guò)其構(gòu)造函數(shù)的參數(shù)函數(shù)對(duì)象將狀態(tài)變?yōu)椤:褪褂媒馕鲋担瑫r(shí)通過(guò)構(gòu)造函數(shù)的參數(shù)的函數(shù)對(duì)象觸發(fā)的狀態(tài)轉(zhuǎn)變,其中使用數(shù)組記錄返回值使用索引值以確保其返回值在結(jié)果集中的順序。 Promise原理分析二 前面我們分析了Promise的then和catch方法,接下來(lái)我們一起來(lái)看看reject、resolve、race和all方法的實(shí)現(xiàn)...

    OnlyMyRailgun 評(píng)論0 收藏0
  • 原理剖析(第 011 篇)Netty之服務(wù)端啟動(dòng)工作原理分析(下)

    摘要:原理剖析第篇之服務(wù)端啟動(dòng)工作原理分析下一大致介紹由于篇幅過(guò)長(zhǎng)難以發(fā)布,所以本章節(jié)接著上一節(jié)來(lái)的,上一章節(jié)為原理剖析第篇之服務(wù)端啟動(dòng)工作原理分析上那么本章節(jié)就繼續(xù)分析的服務(wù)端啟動(dòng),分析的源碼版本為二三四章節(jié)請(qǐng)看上一章節(jié)詳見(jiàn)原理剖析第篇之 原理剖析(第 011 篇)Netty之服務(wù)端啟動(dòng)工作原理分析(下) - 一、大致介紹 1、由于篇幅過(guò)長(zhǎng)難以發(fā)布,所以本章節(jié)接著上一節(jié)來(lái)的,上一章節(jié)為【原...

    Tikitoo 評(píng)論0 收藏0
  • promise/deferred 模式原理分析和實(shí)現(xiàn)

    摘要:三模式模式其實(shí)包含兩部分和。六化在編碼的時(shí)候,想要用進(jìn)行異步操作流程控制,就要將當(dāng)前的異步回調(diào)函數(shù)封裝成。 一、什么是promise/deferred 模式 promise/deferred 模式是,根據(jù)promise/A 或者它的增強(qiáng)修改版promise/A+ 規(guī)范 實(shí)現(xiàn)的promise異步操作的一種實(shí)現(xiàn)方式。 異步的廣度使用使得回調(diào),嵌套出現(xiàn),但是一但出現(xiàn)深度的嵌套,就會(huì)讓codi...

    gclove 評(píng)論0 收藏0
  • js異步發(fā)展歷史與Promise原理分析

    摘要:異步的發(fā)展歷史寫(xiě)法意為回調(diào)函數(shù),即異步操作執(zhí)行完后觸發(fā)執(zhí)行的函數(shù),例如當(dāng)請(qǐng)求完成時(shí)就會(huì)觸發(fā)函數(shù)。實(shí)例生成以后,可以用方法分別指定狀態(tài)和狀態(tài)的回調(diào)函數(shù)。第一個(gè)回調(diào)函數(shù)是對(duì)象的狀態(tài)變?yōu)闀r(shí)調(diào)用,第二個(gè)回調(diào)函數(shù)是對(duì)象的狀態(tài)變?yōu)闀r(shí)調(diào)用。 關(guān)于異步 所謂異步,簡(jiǎn)單說(shuō)就是一個(gè)任務(wù)不是連續(xù)完成的,可以理解成該任務(wù)被人為分成兩段,先執(zhí)行第一段,然后轉(zhuǎn)而執(zhí)行其他任務(wù),等做好了準(zhǔn)備,再回過(guò)頭執(zhí)行第二段。 比...

    jimhs 評(píng)論0 收藏0
  • 30分鐘,讓你徹底明白Promise原理

    摘要:鏈?zhǔn)绞侵冈诋?dāng)前達(dá)到狀態(tài)后,即開(kāi)始進(jìn)行下一個(gè)后鄰。在中發(fā)現(xiàn)沒(méi)有指定異步操作失敗的回調(diào)時(shí),會(huì)直接將函數(shù)返回的,后同設(shè)為狀態(tài),如此達(dá)成執(zhí)行后續(xù)失敗回調(diào)的效果。 原文鏈接 前言 前一陣子記錄了promise的一些常規(guī)用法,這篇文章再深入一個(gè)層次,來(lái)分析分析promise的這種規(guī)則機(jī)制是如何實(shí)現(xiàn)的。ps:本文適合已經(jīng)對(duì)promise的用法有所了解的人閱讀,如果對(duì)其用法還不是太了解,可以移步我的上...

    Profeel 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<