欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS中Promise函數(shù)then的奧秘探究

 更新時(shí)間:2018年07月30日 08:45:56   作者:donglegend  
then()方法用于指定當(dāng)前實(shí)例狀態(tài)發(fā)生改變時(shí)的回調(diào)函數(shù)。它返回一個(gè)新的Promise實(shí)例。下面這篇文章主要給大家介紹了關(guān)于JS中Promise函數(shù)then的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧

Promise概述

Promise對(duì)象是CommonJS工作組提出的一種規(guī)范,目的是為異步操作提供統(tǒng)一接口。

那么,什么是Promises?

首先,它是一個(gè)對(duì)象,也就是說與其他JavaScript對(duì)象的用法,沒有什么兩樣;其次,它起到代理作用(proxy),充當(dāng)異步操作與回調(diào)函數(shù)之間的中介。它使得異步操作具備同步操作的接口,使得程序具備正常的同步運(yùn)行的流程,回調(diào)函數(shù)不必再一層層嵌套。

簡(jiǎn)單說,它的思想是,每一個(gè)異步任務(wù)立刻返回一個(gè)Promise對(duì)象,由于是立刻返回,所以可以采用同步操作的流程。這個(gè)Promises對(duì)象有一個(gè)then方法,允許指定回調(diào)函數(shù),在異步任務(wù)完成后調(diào)用。

Promise的then方法可以接受前一個(gè)函數(shù)的執(zhí)行結(jié)果,還可以保證另一個(gè)Promise的順序執(zhí)行,這到底是怎么做到的呢?

原理圖(先上圖)

問題需求

如何保證多個(gè) promise 順序執(zhí)行?

實(shí)例:

var f1 = function (){
 return new Promise(function (resolve, reject){
  setTimeout(function (){
   console.log("f1 ok!")
   resolve("f1 ok!");
  }, 1000)
 });
}
var f2 = function (){
 return new Promise(function (resolve, reject){
  setTimeout(function (){
   console.log("f2 ok!")
   resolve("f2 ok!");
  }, 3000)
 });
}
var f3 = function (){
 return new Promise(function (resolve, reject){
  setTimeout(function (){
   console.log("f3 ok!")
   resolve("f3 ok!");
  }, 2000)
 });
}

當(dāng)然如果要并行的話,我們很容易想到 Promise.all 方法:

Promise.all([f1(), f2(), f3()]).then(function (data){
 console.log(data)
})
// f1 ok! 
// f3 ok! 
// f2 ok! 
// ["f1 ok!", "f2 ok!", "f3 ok!"]

如果要順序執(zhí)行:

f1().then(f2).then(f3)
// f1 ok!
// f2 ok!
// f3 ok!

//或者這樣

function f(all) {
 var promise = Promise.resolve();
 all.forEach((p, index) => {
  promise = promise.then(p)
 })
}
f([f1, f2, f3])

那么問題來了,then是如何做到順序執(zhí)行的呢,參數(shù)既可以是一個(gè)普通函數(shù),也可是是一個(gè)返回promise的函數(shù)?

then的奧秘

很多實(shí)現(xiàn)promise的庫都比較復(fù)雜,如果自己實(shí)現(xiàn)的話,可以借鑒下面簡(jiǎn)單的代碼:

Promise.prototype.then = function(onFulfilled, onRejected) {
 var promise = this;
 return new Promise(function(resolve, reject) {
  function handle(value) {
   var ret = typeof onFulfilled === 'function' && onFulfilled(value) || value;
   if (ret && typeof ret['then'] == 'function') {
    ret.then(function(value) {
     resolve(value);
    }, function(reason) {
     reject(reason);
    });
   } else {
    resolve(ret);
   }
  }
  function errback(reason) {
   reason = typeof onRejected === 'function' && onRejected(reason) || reason;
   reject(reason);
  }
  if (promise._status === 'PENDING') {
   promise._resolves.push(handle);
   promise._rejects.push(errback);
  } else if (promise._status === FULFILLED) { 
   callback(promise._value);
  } else if (promise._status === REJECTED) {
   errback(promise._reason);
  }
 });
}

重點(diǎn)在then的實(shí)現(xiàn),看上述代碼,每個(gè)then返回的是什么,是一個(gè)新的 Promise,一個(gè)新的 Promise,一個(gè)新的 Promise
第二個(gè)重點(diǎn)是,在內(nèi)部又處理了一個(gè) 回調(diào)函數(shù)運(yùn)行結(jié)果是 一個(gè) promise的 判斷,如果是那么等待這個(gè)promise運(yùn)行結(jié)束才調(diào)用 resolve 更改狀態(tài),關(guān)鍵是resolve的調(diào)用時(shí)機(jī),resolve的調(diào)用時(shí)機(jī),才能夠往下執(zhí)行,這兩步就是then函數(shù)的關(guān)鍵。
是不是 有點(diǎn)暈,請(qǐng)看最開始的圖。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

相關(guān)文章

最新評(píng)論