關(guān)于Promises

一、名字

? ? ? ? promise(首字母小寫):一個對象,Promise的實例對象

? ? ? ? Promise(首字母大寫,單數(shù)):Prmoise構(gòu)造函數(shù)

? ? ? ? Promises(首字母大寫,復(fù)數(shù)):指代Promise規(guī)范

二、Promises/A規(guī)范和ES6 Prmoises規(guī)范

? ? ? ? Prmoises規(guī)范有幾次升級,目前來說,Promises/A是最新的民間規(guī)范。ES6 Prmoises是最新的官方規(guī)范。

三、Promises的意義

? ? ? ? 1、解決回調(diào)金字塔的問題(回調(diào)圣誕樹,回調(diào)地獄)

? ? ? ? 2、可以同時管理成功回調(diào)和失敗回調(diào)

四、所謂“承諾”

? ? ? ? Promises這個單詞翻譯為“承諾”。程序的世界里,理解為:我承諾給你完成這些代碼的執(zhí)行。new有一個Prmoise實例,就是js引擎給你一個承諾。

? ? ? ? 執(zhí)行承諾,就會有成功或者失敗,只是概率問題。

? ? ? ? 在程序世界里,一個承諾也只會有三種狀態(tài):“未解決(pendding)”、“成功的(resolve)”、“失敗的(reject)”。

五、Promise構(gòu)造函數(shù)的能力

? ? ? ? 本質(zhì):prmoises寫法的本質(zhì)就是把 異步寫法擼成同步寫法。

? ? ? ? 怎么做到的呢?

????????就是安排一下代碼執(zhí)行的先后順序:Promise構(gòu)造函數(shù)有特殊的功能,傳入Prmoise構(gòu)造函數(shù)的函數(shù)參數(shù)會優(yōu)先第一執(zhí)行,也就是說,只要new一個Prmoise,那么Promise構(gòu)造函數(shù)的函數(shù)參數(shù)是最高優(yōu)先級執(zhí)行的,一直到new一個Promise對象實例后面的then()代碼才會執(zhí)行。鏈條行的每一個then()都會等到前面promise有了結(jié)果才會執(zhí)行。

? ? ? ? Promise是一個構(gòu)造函數(shù),用來生成prmoise實例。

? ? ? ? Promise構(gòu)造函數(shù)接受一個函數(shù)作為參數(shù),這個函數(shù)的兩個參數(shù)分別是:resolve和reject。他們是兩個函數(shù),有js引擎提供(自帶的。

? ? ? ? resolve函數(shù)的作用:將promise對象的狀態(tài)從“未完成”變成“成功”。在異步操作成功時調(diào)用,并將異步的結(jié)果作為參數(shù)傳遞出去。

? ? ? ? reject函數(shù)的通:將promise對象的狀態(tài)從“未完成”變成“失敗”。在異步操作失敗的時候調(diào)用,并將錯誤作為參數(shù)傳遞出去。

? ? ? ? promise對象生成以后,可以用then()方法分別制定resolve狀態(tài)和reject狀態(tài)的回到函數(shù)

六、擼代碼

? ? ? ? 傳統(tǒng)的回調(diào)地獄寫法:

? ? ? ? ? ? ? ? firstAsync(function(data){

? ? ? ? ? ? ? ? ? ? //拿到data的數(shù)據(jù) 處理業(yè)務(wù)邏輯 do something

? ? ? ? ? ? ? ? ? ? secondAsync(function(data2){

? ???????????????????????//拿到data2的數(shù)據(jù) 處理業(yè)務(wù)邏輯?do something

? ? ? ? ? ? ? ? ? ? ? ? thirdAsync(function(data3){

? ??????????????????????????????//拿到data3的數(shù)據(jù) 處理業(yè)務(wù)邏輯?do something

????????????????????????})

????????????????????})

????????????????})

? ? ? ?哈哈哈,像不像一個金字塔。可讀性和維護性都比較差

? ? ? ? 引入Promise的寫法:

? ??????firstAsync().then(function(data){

? ??????????????//拿到data的數(shù)據(jù) 處理業(yè)務(wù)邏輯 do something

? ? ? ? ? ? ? ? return?secondAsync() //繼續(xù)處理第二個異步

????????}).then(function(data2){

? ??????????//拿到data2的數(shù)據(jù) 處理業(yè)務(wù)邏輯 do something

? ? ? ? ? ? return?thirdAsync() //繼續(xù)處理第二個異步

????????}).then(function(data3){

? ??????????????//拿到data3的數(shù)據(jù) 處理業(yè)務(wù)邏輯 do something

????????})

? ? ? ? 通過then的鏈式寫法,把回調(diào)按照順序串聯(lián)起來。

? ? ? ? 更直接的例子:有做飯、吃飯、洗碗筷這三個異步的操作,他們是層層依賴,下一步的操作依賴上一步操作的結(jié)果

? ? ? ? =》

? ??????(1)下面通過樣例作為演示,我們定義做飯、吃飯、洗碗(cook、eat、wash)這三個方法,它們是層層依賴的關(guān)系,下一步的的操作需要使用上一部操作的結(jié)果。(這里使用?setTimeout?模擬異步操作)

? ? ????????????//做飯? ??

function cook(){

console.log("開始做飯");

var p = new Promise(function(resolve,reject){

setTimeout(function(){

console.log("做飯完畢")

resolve("老北京炸醬面")

},1000)

})

return p;

}

//吃飯

function eat(data){

console.log("開始吃飯:"+data)

var p = new Promise(function(resolve,reject){

setTimeout(function(){

console.log("吃飽啦")

resolve("筷子盤子碗")

},2000)

})

return p

}

//洗碗筷

function wash(data){

console.log("開始洗碗筷:"+data)

var p = new Promise(function(resolve,reject){

setTimeout(function(){

console.log("洗好啦")

resolve("干凈的碗筷")

},2000)

})

return p

}


(2)使用?then?鏈式調(diào)用這三個方法:

cook()

.then(function(data){

????returneat(data);

})

.then(function(data){

????returnwash(data);

})

.then(function(data){

????console.log(data);

});


好了,看運行的結(jié)果:

Promises.html:14 開始做飯

Promises.html:17 做飯完畢

Promises.html:26 開始吃飯:老北京炸醬面

Promises.html:29 吃飽啦

Promises.html:39 開始洗碗筷:筷子盤子碗

Promises.html:42 洗好啦

Promises.html:54 干凈的碗筷


七、all

? ? ? ? Promises的all方法,拓展了異步操作的能力,即在所有指定的異步操作都結(jié)束后才運行回調(diào)。

? ? ? ? 直接上代碼:

? ? ? ??//切菜

function cut(){

console.log("開始切菜:青菜")

var p = new Promise(function(resolve,reject){

setTimeout(function(){

console.log("切菜完畢")

resolve("切好的青菜")

},1000)

})

return p

}

//燒水

function boil(){

console.log("開始燒水")

var p = new Promise(function(resolve,reject){

setTimeout(function(){

console.log("燒水完畢")

resolve("燒好的水")

},2000)

})

return p

}

//all then把操作邏輯串起來

Promise.all([cut(),boil()]).then(function(data){

console.log("準備工作完畢")

console.log(data)

})


結(jié)果:

開始切菜:青菜

Promises.html:72 開始燒水

Promises.html:64 切菜完畢

Promises.html:76 燒水完畢

Promises.html:84 準備工作完畢

Promises.html:85 ["切好的青菜", "燒好的水"]

八、Promises的race方法:和all類似,是異步能力的拓展,區(qū)別是all是所有異步操作都結(jié)束才能執(zhí)行回調(diào),?race?的話只要有一個異步操作執(zhí)行完畢,就立刻執(zhí)行?then?回調(diào)。

注意:其它沒有執(zhí)行完畢的異步操作仍然會繼續(xù)執(zhí)行,而不是停止。

上面的切菜燒水操作定義好以后:

Promise.race([cut(),boil()]).then(function(data){

console.log("至少有一個工作準備好了")

console.log(data)

})


結(jié)果注意順序:

開始切菜:青菜

Promises.html:72 開始燒水

Promises.html:64 切菜完畢

Promises.html:89 至少有一個工作準備好了

Promises.html:90 切好的青菜

Promises.html:76 燒水完畢

注意,race的應(yīng)用場景很多,比如同時向后臺發(fā)起多個ajax的異步請求,并且都有超時時間設(shè)置。

比如:

//請求某個圖片資源

function requestImg(){

? ? var p = new Promise(function(resolve, reject){

? ? var img = new Image();

? ? img.onload = function(){

? ? ? resolve(img);

? ? }

? ? img.src = 'xxxxxx';

? ? });

? ? return p;

}

//延時函數(shù),用于給請求計時

function timeout(){

? ? var p = new Promise(function(resolve, reject){

? ? ? ? setTimeout(function(){

? ? ? ? ? ? reject('圖片請求超時');

? ? ? ? }, 5000);

? ? });

? ? return p;

}

Promise

.race([requestImg(), timeout()])

.then(function(results){

? ? console.log(results);

})

.catch(function(reason){

? ? console.log(reason);

});

上面代碼?requestImg?函數(shù)異步請求一張圖片,timeout?函數(shù)是一個延時?5?秒的異步操作。我們將它們一起放在?race?中賽跑。

如果?5?秒內(nèi)圖片請求成功那么便進入?then?方法,執(zhí)行正常的流程。

如果?5?秒鐘圖片還未成功返回,那么則進入?catch,報“圖片請求超時”的信息。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Promise 對象 Promise 的含義 Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案——回調(diào)函...
    neromous閱讀 8,831評論 1 56
  • 本文適用的讀者 本文寫給有一定Promise使用經(jīng)驗的人,如果你還沒有使用過Promise,這篇文章可能不適合你,...
    HZ充電大喵閱讀 7,453評論 6 19
  • 一、Promise的含義 Promise在JavaScript語言中早有實現(xiàn),ES6將其寫進了語言標準,統(tǒng)一了用法...
    Alex灌湯貓閱讀 887評論 0 2
  • 歡迎閱讀專門探索 JavaScript 及其構(gòu)建組件的系列文章的第四章。 在識別和描述核心元素的過程中,我們還分享...
    OSC開源社區(qū)閱讀 1,217評論 1 10
  • 城市的上空密密麻麻 廣闊的網(wǎng)眼里篩入空氣和水 人們披著斑斕的長衣服 用舞蹈代替行走 地面并不存在 無底的深淵奇花蔓...
    孟小繁閱讀 232評論 0 0

友情鏈接更多精彩內(nèi)容