摘要:換句話說(shuō)該靜態(tài)函數(shù)返回個(gè)處于狀態(tài)的對(duì)象。等價(jià)于構(gòu)造函數(shù)的靜態(tài)函數(shù),創(chuàng)建一個(gè)對(duì)象并以值作為參數(shù)調(diào)用句柄函數(shù)。等價(jià)于介紹構(gòu)造函數(shù)的靜態(tài)函數(shù),參數(shù)是對(duì)象組成的可迭代數(shù)據(jù)集合。
一、概述
ES2015 Promise函數(shù)是對(duì)PromiseA+標(biāo)準(zhǔn)的實(shí)現(xiàn),并且嚴(yán)格遵守該標(biāo)準(zhǔn)。
二、APIs 2.1 創(chuàng)建Promise對(duì)象Promise構(gòu)造函數(shù)的參數(shù)是個(gè)包含兩個(gè)參數(shù)的函數(shù),并且該函數(shù)的參數(shù)分別對(duì)應(yīng)resolve, reject操作(resolve,reject也是函數(shù))。并且只能通過(guò)這兩個(gè)參數(shù)改變Promise的狀態(tài)。
function asynOperation(){ var promise = new Promise(function(resolve, reject){ setTimeout(function(){ reject(1,2,3); // 調(diào)用reject操作,并傳遞reason參數(shù)。雖然傳遞多個(gè)參數(shù),但只把第一個(gè)作為reson值,符合Promise A+標(biāo)準(zhǔn) }, 3000) }); return promise; } asynOperation().then(function(value){ console.log("ES2015 Promise: resolved and value is " + value); }, function(reason){ console.log("ES2015 Promise: rejected and reason is " + reason); })
上面的代碼用zpotojs實(shí)現(xiàn):
/* ZeptoJS Deferred */ function AsynOperation1(){ var deferred = $.Deferred(); setTimeout(function(){ deferred.reject(1, 2, 3); }, 3000); return deferred.promise(); } AsynOperation1().then(function(val){ console.log("Fullfilled: " + val); }, function(reason){ console.log("Rejected: " + reason); })2.2 Promise.prototype.catch
catch方法用來(lái)添加Rejected狀態(tài)回調(diào),是then方法的一種子集。
asynOperation().catch(function(reason){ }) // 等價(jià)于 asynOperation().then(undefined, function(reason){ })2.3 Promise.reject(reason)
Promise構(gòu)造函數(shù)的靜態(tài)方法,創(chuàng)建個(gè)Promise對(duì)象并以reason值調(diào)用reject句柄函數(shù)。換句話說(shuō)該靜態(tài)函數(shù)返回個(gè)處于“Rejected”狀態(tài)的Promise對(duì)象。
var p = Promise.reject(1); // 等價(jià)于 var p = new Promise(function(resolve, reject){ reject(1); })2.4 Promise.resolve(value)
Promise構(gòu)造函數(shù)的靜態(tài)函數(shù),創(chuàng)建一個(gè)Promise對(duì)象并以value值作為參數(shù)調(diào)用resolve句柄函數(shù)。換句話說(shuō)該靜態(tài)函數(shù)返回個(gè)處于“fullfilled"狀態(tài)的Promise對(duì)象。
var p = Promise.resolve(1); // 等價(jià)于 var = new Promise(function(resolve){ resolve(1); })2.5 Promise.all(iterable) 2.5.1 介紹
Promise構(gòu)造函數(shù)的靜態(tài)函數(shù),參數(shù)是Promise對(duì)象組成的可迭代數(shù)據(jù)集合。創(chuàng)建個(gè)Promise對(duì)象,并且參數(shù)指定的所以Promise都解決后,該P(yáng)romise對(duì)象該被解決,反之如果其中存在rejected的Promise,則該P(yáng)romise對(duì)象被rejected。
定義個(gè)異步操作:
function asynOperation(value, reason){ var promise = new Promise(function(resolve, reject){ setTimeout(function(){ value === undefined ? reject(reason) : resolve(value); }, 3000) }); return promise; } var p1 = asynOperation(1), p2 = asynOperation(2), p3 = asynOperation(3); Promise.all([p1, p2, p3]).then(function(value){ console.log("all resolved: value is " + value); // value是[1, 2, 3] })
如果參數(shù)元素中發(fā)生rejected操作,則立馬reject返回的Promise:
var p1 = asynOperation(1), p2 = asynOperation(undefined, 2), // reject操作 p3 = asynOperation(undefined, 3); // reject操作 p2.catch(function(reson){ console.log("p2") }) p3.catch(function(reson){ console.log("p3") }) Promise.all([p1, p2, p3]).then(function(value){ console.log("all resolved: value is " + value) }, function(reason){ console.log("one rejected: reason is " + reason); // reson值等于發(fā)生reject操作的promise對(duì)象的reason,即p2 })
顯示結(jié)果:
2.5.2 對(duì)比$.whenPromise.all和$.when很類似。主題功能差不多,參數(shù)傳遞方式不一樣:ES2015中把所有的Promise對(duì)象的value構(gòu)建個(gè)數(shù)組,而$.when是分別傳遞的。
function AsynOperation1(value, reason){ var deferred = $.Deferred(); setTimeout(function(){ value === undefined ? deferred.reject(reason) : deferred.resolve(value); }, 3000); return deferred.promise(); } var p1 = AsynOperation1(1), p2 = AsynOperation1(2), p3 = AsynOperation1(3); $.when(p1, p2, p3).then(function(value){ console.log("resolved " + value); // 留意Value的值 }, function(reason){ console.log("rejected " + reason); })2.6 Promise.race(iterable)
Promise構(gòu)造函數(shù)的靜態(tài)函數(shù),參數(shù)是Promise對(duì)象構(gòu)成的可迭代對(duì)象,創(chuàng)建個(gè)Promise對(duì)象。當(dāng)參數(shù)任意Promise對(duì)象fullfilled(rejected)時(shí),則立馬fullfill(reject)該P(yáng)romise對(duì)象。
var p1 = asynOperation(1), p2 = asynOperation(undefined, 2), p3 = asynOperation(undefined, 3); Promise.race([p1, p2, p3]).then(function(value){ console.log("one resolved: value is " + value); // Value=1 }, function(reason){ console.log("one rejected: reason is " + reason) })三、micro-task
Promise的回調(diào)通過(guò)micor-task實(shí)現(xiàn)的。
console.log(1) setTimeout(function(){ console.log(2)}, 0) Promise.resolve().then(function(){console.log(3)}) console.log(4) // 輸出應(yīng)該是:1 4 3 2四、對(duì)比Promise A+ 標(biāo)準(zhǔn)
大部分Promise A+標(biāo)準(zhǔn)的實(shí)現(xiàn)對(duì)"Promise解決過(guò)程"標(biāo)準(zhǔn)的實(shí)現(xiàn)略有不同,比如zeptoJs Deferred就沒(méi)考慮thenable情況。但是ES2015 Promise函數(shù)完全嚴(yán)格遵守Promise A+標(biāo)準(zhǔn),包含對(duì)“Promise 解決過(guò)程的實(shí)現(xiàn)。下面舉例說(shuō)明實(shí)現(xiàn)Promise解決過(guò)程(The Promise Resolution Procedure):[[Resolve]](promise, x)
3.3.1 如果promise對(duì)象和x相等,則用TypeError對(duì)象作為reason 拒絕promise對(duì)象var p1 = asynOperation(1); var p2 = p1.then(function(value){ console.log("resolved: " + value); return p2; // 返回p2對(duì)象, },function(reason){ console.log("rejected: " + reason); }}; }); p2.then(function(value){ console.log("resolved: " + value); },function(reason){ console.log("rejected: " + reason);
var p1 = asynOperation(1); var p2 = p1.then(function(value){ console.log("resolved: " + value); return asynOperation(2); // 返回個(gè)Promise對(duì)象,以該P(yáng)rmoise對(duì)象狀態(tài)決定p2的狀態(tài) },function(reason){ console.log("rejected: " + reason); }); p2.then(function(value){ console.log("resolved: " + value); },function(reason){ console.log("rejected: " + reason); })3.3.3 如果x是thenable,promise狀態(tài)的改變?nèi)Q于x.then方法的執(zhí)行中resolve,reject句柄的調(diào)用情況。并不受x.then返回值的影響。
A:then方法沒(méi)有調(diào)用resolve或者reject,并且沒(méi)有返回值,則不會(huì)改變promose的狀態(tài)
var p1 = asynOperation(1); var p2 = p1.then(function(value){ console.log("resolved: " + value); return {name: "john", then: function(resolve, reject){ // 返回值是個(gè)thenable對(duì)象,但是then方法沒(méi)有調(diào)用resolve或者reject,并且沒(méi)有返回值 }}; },function(reason){ console.log("rejected: " + reason); }); p2.then(function(value){ console.log("resolved: " + value); },function(reason){ console.log("rejected: " + reason); })
B:then方法中調(diào)用resolve句柄,用新value y遞歸調(diào)用Promise解決過(guò)程:[[Resolve]](promise, y)
var p1 = asynOperation(1); var p2 = p1.then(function(value){ console.log("resolved: " + value); return {name: "john", then: function(resolve, reject){ resolve(2); // then方法中調(diào)用resolve句柄,用新value遞歸調(diào)用Promise解決過(guò)程 }}; },function(reason){ console.log("rejected: " + reason); }); p2.then(function(value){ console.log("resolved: " + value); },function(reason){ console.log("rejected: " + reason); })
C:then方法中調(diào)用reject句柄,則用相同的reason拒絕promise.
var p1 = asynOperation(1); var p2 = p1.then(function(value){ console.log("resolved: " + value); return {name: "john", then: function(resolve, reject){ reject(2); // 調(diào)用reject句柄 }}; },function(reason){ console.log("rejected: " + reason); }); p2.then(function(value){ console.log("resolved: " + value); },function(reason){ console.log("rejected: " + reason); })
D:then方法中多次調(diào)用resolve, reject句柄,只有第一個(gè)調(diào)用有效,其他的忽略
E:then方法中拋異常,如果拋異常之前已經(jīng)調(diào)用resolve或者reject句柄,則忽略該異常,反之則以該異常為reason拒絕promise
2.3.4 其他情況,則用x作為value完成promise。var p1 = asynOperation(undefined, 1); // 拒絕的promise var p2 = p1.then(function(value){ console.log("resolved: " + value); return {name: "john"}; },function(reason){ console.log("rejected: " + reason); return 2; }); p2.then(function(value){ console.log("resolved: " + value); },function(reason){ console.log("rejected: " + reason); })還沒(méi)結(jié)束
一道關(guān)于Promise應(yīng)用的面試題
參考是時(shí)候使用promise了
avaScript Promise迷你書(中文版)
MDN
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/93321.html
摘要:的翻譯文檔由的維護(hù)很多人說(shuō),阮老師已經(jīng)有一本關(guān)于的書了入門,覺(jué)得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開(kāi)發(fā)過(guò)程中,顯得越來(lái)越重要。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...
摘要:和和都有和,但是略有不同。實(shí)際上返回的是一個(gè)對(duì)象。和添加的回調(diào),添加的回調(diào)。所以在調(diào)用成功的情況下執(zhí)行添加的回調(diào),調(diào)用失敗時(shí)執(zhí)行添加的回調(diào)。,產(chǎn)生對(duì)象并,產(chǎn)生對(duì)象并,然后繼續(xù)處理,的語(yǔ)法糖,和的差不多但不同。 Deferred 和 Promise ES6 和 jQuery 都有 Deffered 和 Promise,但是略有不同。不過(guò)它們的作用可以簡(jiǎn)單的用兩句話來(lái)描述 Deffere...
摘要:所謂異步編程中的異步是相對(duì)于同步的概念的。是一系列異步編程規(guī)范的統(tǒng)稱。如果中的回調(diào)函數(shù)返回一個(gè)值,那么返回的將會(huì)成為接受狀態(tài),并且將返回的值作為接受狀態(tài)的回調(diào)函數(shù)的參數(shù)值。參考介紹基礎(chǔ)篇深入理解與異步編程。 es6 promise與異步編程 對(duì)于一些還不具備大量編程經(jīng)驗(yàn)的朋友來(lái)說(shuō),promise可能是es6比較難以掌握的點(diǎn)。首先是很多名詞,比如Promises,es6 Promise,...
摘要:從最開(kāi)始的到封裝后的都在試圖解決異步編程過(guò)程中的問(wèn)題。為了讓編程更美好,我們就需要引入來(lái)降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來(lái)處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問(wèn)題描述 在開(kāi)發(fā)過(guò)程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過(guò)http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過(guò)...
摘要:如果有錯(cuò)誤,則到的第二個(gè)回調(diào)函數(shù)中,對(duì)錯(cuò)誤進(jìn)行處理。假設(shè)第一個(gè)的第一個(gè)回調(diào)沒(méi)有返回一個(gè)對(duì)象,那么第二個(gè)的調(diào)用者還是原來(lái)的對(duì)象,只不過(guò)其的值變成了第一個(gè)中第一個(gè)回調(diào)函數(shù)的返回值。 ES6標(biāo)準(zhǔn)出爐之前,一個(gè)幽靈,回調(diào)的幽靈,游蕩在JavaScript世界。 正所謂: 世界本沒(méi)有回調(diào),寫的人多了,也就有了})})})})})。 Promise的興起,是因?yàn)楫惒椒椒ㄕ{(diào)用中,往往會(huì)出現(xiàn)回調(diào)函數(shù)一...
摘要:就算改變已經(jīng)發(fā)生了,即使再對(duì)對(duì)象添加回調(diào)函數(shù),也會(huì)立即得到這個(gè)結(jié)果。方法接收個(gè)參數(shù),第一個(gè)參數(shù)是狀態(tài)的回調(diào)函數(shù),第二個(gè)參數(shù)可選是狀態(tài)的回調(diào)函數(shù)。簡(jiǎn)單來(lái)講,就是能把原來(lái)的回調(diào)寫法分離出來(lái),在異步操作執(zhí)行完后,用鏈?zhǔn)秸{(diào)用的方式執(zhí)行回調(diào)函數(shù)。 在ECMAScript 6標(biāo)準(zhǔn)中,Promise被正式列為規(guī)范,Promise,字面意思就是許諾,承諾,嘿,聽(tīng)著是不是很浪漫的說(shuō)?我們來(lái)探究一下這個(gè)浪...
閱讀 1756·2021-11-11 10:58
閱讀 4277·2021-09-09 09:33
閱讀 1285·2021-08-18 10:23
閱讀 1576·2019-08-30 15:52
閱讀 1664·2019-08-30 11:06
閱讀 1901·2019-08-29 14:03
閱讀 1536·2019-08-26 14:06
閱讀 2999·2019-08-26 10:39