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的庫(kù)都比較復(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)看最開始的圖。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96345.html
摘要:它的作用是為實(shí)例添加狀態(tài)改變時(shí)的回調(diào)函數(shù)。里面有兩個(gè)回調(diào)函數(shù),前者返回的回調(diào)函數(shù),后者是可選值??梢钥闯墒堑膭e名專門用來指定錯(cuò)誤發(fā)生時(shí)的回調(diào)函數(shù)。 最近一直私下在看Android項(xiàng)目,前端這一塊沒怎么仔細(xì)研究。昨天在寫重構(gòu)公司前端項(xiàng)目的時(shí)候,我發(fā)現(xiàn)一旦有異步的任務(wù),腦海里面條件反射一般的出現(xiàn)promise的字樣。重構(gòu)的多了 心就就在納悶:既然promise這么好用,我能不能自己手寫一個(gè)pro...
摘要:構(gòu)造函數(shù)的實(shí)現(xiàn)我們?cè)谑褂玫臅r(shí)候其實(shí)是使用關(guān)鍵字創(chuàng)建了一個(gè)的實(shí)例,其實(shí)是一個(gè)類,即構(gòu)造函數(shù),下面來實(shí)現(xiàn)構(gòu)造函數(shù)。 showImg(https://segmentfault.com/img/remote/1460000018998456); 閱讀原文 概述 Promise 是 js 異步編程的一種解決方案,避免了 回調(diào)地獄 給編程帶來的麻煩,在 ES6 中成為了標(biāo)準(zhǔn),這篇文章重點(diǎn)不是敘...
摘要:處理和前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤發(fā)生錯(cuò)誤對(duì)象的錯(cuò)誤具有冒泡性質(zhì),會(huì)一直向后傳遞,直到被捕獲為止。 0 前言 我一直以為我對(duì)Promise比較了解,相關(guān)的方法已經(jīng)非常熟悉了,直到我看到這篇文章,里面提出了這樣一個(gè)問題:Q: 假定 doSomething() 和 doSomethingElse() 均返回 promises,下面的四種 promises 的區(qū)別是什么 /...
摘要:就是每次傳入的函數(shù)最后是的任務(wù)之后,開始執(zhí)行,可以看到此時(shí)會(huì)批量執(zhí)行中的函數(shù),而且還給這些中回調(diào)函數(shù)放入了一個(gè)這個(gè)很顯眼的函數(shù)之中,表示這些回調(diào)函數(shù)是在微任務(wù)中執(zhí)行的。下一模塊會(huì)對(duì)此微任務(wù)中的插隊(duì)行為進(jìn)行詳解。 有關(guān)Eventloop+Promise的面試題大約分以下幾個(gè)版本——得心應(yīng)手版、游刃有余版、爐火純青版、登峰造極版和究極變態(tài)版。假設(shè)小伙伴們戰(zhàn)到最后一題,以后遇到此類問題,都是...
摘要:構(gòu)造函數(shù)規(guī)定,對(duì)象是一個(gè)構(gòu)造函數(shù),用來生成實(shí)例。如果中的回調(diào)函數(shù)拋出一個(gè)錯(cuò)誤,那么返回的將會(huì)成為拒絕狀態(tài),并且將拋出的錯(cuò)誤作為拒絕狀態(tài)的回調(diào)函數(shù)的參數(shù)值。 其實(shí)想寫 Promise 的使用已經(jīng)很長(zhǎng)時(shí)間了。一個(gè)是在實(shí)際編碼的過程中經(jīng)常用到,一個(gè)是確實(shí)有時(shí)候小伙伴們?cè)谑褂脮r(shí)也會(huì)遇到一些問題。Promise 也確實(shí)是 ES6 中 對(duì)于寫 JS 的方式,有著真正最大影響的 API 特性之一。本...
閱讀 1695·2019-08-30 15:54
閱讀 3346·2019-08-26 17:15
閱讀 3536·2019-08-26 13:49
閱讀 2589·2019-08-26 13:38
閱讀 2301·2019-08-26 12:08
閱讀 3065·2019-08-26 10:41
閱讀 1379·2019-08-26 10:24
閱讀 3387·2019-08-23 18:35