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