最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談JavaScript中promise的使用

 更新時(shí)間:2017年01月11日 08:59:04   作者:咸魚老弟  
本文主要對(duì)JavaScript中promise的使用進(jìn)行詳細(xì)介紹。具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧

閱讀目錄

  • 什么是Prmoise
  • Promise的使用

最近在看《你不知道的javascript中卷》,發(fā)覺(jué)作者花了基本一半的篇幅去講異步和promise,覺(jué)得有必要總結(jié)一下。

其實(shí)本文的目的是想手寫一個(gè)Promise的,無(wú)奈總結(jié)著總結(jié)著發(fā)覺(jué)篇幅有點(diǎn)長(zhǎng),因此只好一分為二,先介紹promise的用法,知道怎么用,我們才知道怎么寫,所以把手寫一個(gè)promise的任務(wù)放到了下一篇文章當(dāng)中。

當(dāng)然,網(wǎng)上有很多關(guān)于promise的文章,都可以參考參考,有誤之處,歡迎之處。

什么是Prmoise

promise是ES6新增的一個(gè)特征,它已被列入ES6的正式規(guī)范中

Promise對(duì)象可以理解為一次執(zhí)行的異步操作,使用promise對(duì)象之后可以使用一種鏈?zhǔn)秸{(diào)用的方式來(lái)組織代碼;讓代碼更加的直觀。也就是說(shuō),有了Promise對(duì)象,就可以將異步操作以同步的操作的流程表達(dá)出來(lái),避免了層層嵌套的回調(diào)函數(shù)。

示例:未使用promise,回調(diào)必須層層嵌套

$.ajax(url1, function(data1){
 // do something...
 $.ajax(url2, function(data2){
 // do something...
 $.ajax(url3, function(data3){
 // do something...
 done(data3); // 返回?cái)?shù)據(jù)
 })
 });
});

如果有多個(gè)嵌套,導(dǎo)致代碼不夠直觀,而且如果幾個(gè)操作之前沒(méi)有前后順序之分,需要等待上一個(gè)操作完成才可以進(jìn)行下一個(gè)操作,造成不必要的等待

promise就是為了解決這些問(wèn)題而產(chǎn)生的。

Promise對(duì)象的特點(diǎn):

1、對(duì)象的狀態(tài)不受外界影響。

Promise對(duì)象代表一個(gè)異步操作,有三種狀態(tài)

  • pending(執(zhí)行中)
  • Resolved(成功,又稱Fulfilled)
  • rejected(拒絕)

其中pending為初始狀態(tài),fulfilled和rejected為結(jié)束狀態(tài)(結(jié)束狀態(tài)表示promise的生命周期已結(jié)束)。

promise只有異步操作的結(jié)果,可以決定當(dāng)前是哪一種狀態(tài),任何其他操作都無(wú)法改變這個(gè)狀態(tài).。

2、一旦狀態(tài)改變,就不會(huì)再變,任何時(shí)候都可以得到這個(gè)結(jié)果。

Promise對(duì)象的狀態(tài)改變,只有兩種可能:從Pending變?yōu)镽esolved和從Pending變?yōu)镽ejected

pending->fulfilled,pending->rejected。

只要這兩種情況發(fā)生,狀態(tài)就凝固了,不會(huì)再變了,會(huì)一直保持這個(gè)結(jié)果

Promise對(duì)象的缺點(diǎn):

1、無(wú)法取消Promise,一旦新建它就會(huì)立即執(zhí)行,無(wú)法中途取消。

2、如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。

3、當(dāng)處于Pending狀態(tài)時(shí),無(wú)法得知目前進(jìn)展到哪一個(gè)階段(剛剛開始還是即將完成)。

promise兼容性

除了IE這種古老的瀏覽器和一些低版本的安卓外,現(xiàn)代瀏覽器支持還是挺好的,所以我們可以在谷歌的控制臺(tái)直接測(cè)試我們的代碼

Promise的使用

先提前說(shuō)明一下,下面的代碼示例,都可以復(fù)制到谷歌的控制臺(tái)就行測(cè)試??!

1、基本用法:

(1)、首先我們new一個(gè)Promise,將Promise實(shí)例化

(2)、然后在實(shí)例化的promise可以傳兩個(gè)參數(shù),一個(gè)是成功之后的resolve,一個(gè)是失敗之后的reject

(3)、Promise實(shí)例生成以后,可以用then方法分別指定Resolved狀態(tài)和Reject狀態(tài)的回調(diào)函數(shù)

代碼如下:

var promise = function(isReady){
 return new Promise(function(resolve, reject){
 // do somthing, maybe async
 if (isReady){
  return resolve('hello world');
 } else {
  return reject('failure');
 }
 });
}
//Promise實(shí)例生成以后,可以用then方法分別指定Resolved狀態(tài)和Reject狀態(tài)的回調(diào)函數(shù)。
promise(true).then(function(value){
 // success,這里是resolve的回調(diào)函數(shù)
 console.log(value); //hello world
}, function(err){
 // failure,這里是reject的回調(diào)函數(shù)
 console.log(err)
})

上述代碼是執(zhí)行成功,返回hello world,如果想測(cè)試一下失敗后的返回值,可以在promise(true).then...這里改為 promise(false).then...即可

2、鏈?zhǔn)讲僮?/strong>

也許你會(huì)說(shuō),Promise只是簡(jiǎn)化層層回調(diào)的寫法而已吧,其實(shí)不然,它的精髓是通過(guò)維護(hù)狀態(tài)、傳遞狀態(tài)的方式來(lái)使回調(diào)方式能夠及時(shí)的調(diào)用,因此,相比于callback,它更靈活,更簡(jiǎn)單。下面我們來(lái)看看Promise的鏈?zhǔn)讲僮鳎?/p>

makePromise1()
.then(function(value){
 console.log(value);
 return makePromise2();
})
.then(function(value){
 console.log(value);
 return makePromise3();
})
.then(function(value){
 console.log(value);
});
function makePromise1(){
 var p = new Promise(function(resolve, reject){
 //異步操作
 setTimeout(function(){
  console.log('異步任務(wù)1');
  resolve('異步任務(wù)1傳過(guò)來(lái)的值');
 }, 2000);
 });
 return p;  
}
function makePromise2(){
 var p = new Promise(function(resolve, reject){
 //異步操作
 setTimeout(function(){
  console.log('異步任務(wù)2');
  resolve('異步任務(wù)2傳過(guò)來(lái)的值');
 }, 2000);
 });
 return p;  
}
function makePromise3(){
 var p = new Promise(function(resolve, reject){
 //異步操作
 setTimeout(function(){
  console.log('異步任務(wù)3');
  resolve('異步任務(wù)3傳過(guò)來(lái)的值');
 }, 2000);
 });
 return p;  
}

上面的代碼中,我們有三個(gè)異步操作,makePromise1,makePromise2,makePromise3。其中第二個(gè)和第三個(gè)依次執(zhí)行,也就是上一個(gè)操作完成之后才可以進(jìn)行。

輸出的值為:

異步任務(wù)1
異步任務(wù)1傳過(guò)來(lái)的值
異步任務(wù)2
異步任務(wù)2傳過(guò)來(lái)的值
異步任務(wù)3
異步任務(wù)3傳過(guò)來(lái)的值

3、Promise的catch方法

var promise = function(isReady){
 return new Promise(function(resolve, reject){
 // do somthing, maybe async
 if (isReady){
  return resolve('hello world');
 } else {
  return reject('failure');
 }
 });
}
promise(true)
.then(function(value){
 console.log('resolved');
 console.log(value);
 console.log(haha); //此處的haha未定義
})
.catch(function(error){
 console.log('rejected');
 console.log(error);
});

catch 方法是 then(onFulfilled, onRejected) 方法當(dāng)中 onRejected 函數(shù)的一個(gè)簡(jiǎn)單的寫法,也就是說(shuō)可以寫成 then(fn).catch(fn),相當(dāng)于 then(fn).then(null, fn)

使用 catch 的寫法比一般的寫法更加清晰明確,其實(shí)可以類比成try/catch,這樣,其中有報(bào)錯(cuò)的地方不會(huì)阻塞運(yùn)行。比如定義了一個(gè)未定義haha,正常來(lái)說(shuō)它上面的代碼也不會(huì)運(yùn)行,因?yàn)楸贿@個(gè)報(bào)錯(cuò)阻塞了,有了catch,它上面的代碼可以正常運(yùn)行下去:

控制臺(tái)打印出來(lái)的東西:

resolved
hello world
rejected
ReferenceError: haha is not defined(…)

4、promise.all方法

Promise.all 可以接收一個(gè)元素為 Promise 對(duì)象的數(shù)組作為參數(shù),當(dāng)這個(gè)數(shù)組里面所有的 Promise 對(duì)象都變?yōu)?resolve 時(shí),該方法才會(huì)返回。

代碼示例:

var p1 = new Promise(function (resolve) {
 setTimeout(function () {
 resolve("第一個(gè)promise");
 }, 3000);
});
var p2 = new Promise(function (resolve) {
 setTimeout(function () {
 resolve("第二個(gè)promise");
 }, 1000);
});
Promise.all([p1, p2]).then(function (result) {
 console.log(result); // ["第一個(gè)promise", "第二個(gè)promise"]
});

上面的代碼中,all接收一個(gè)數(shù)組作為參數(shù),p1,p2是并行執(zhí)行的,等兩個(gè)都執(zhí)行完了,才會(huì)進(jìn)入到then,all會(huì)把所有的結(jié)果放到一個(gè)數(shù)組中返回,所以我們打印出我們的結(jié)果為一個(gè)數(shù)組。

值得注意的是,雖然p2的執(zhí)行順序比p1快,但是all會(huì)按照參數(shù)里面的數(shù)組順序來(lái)返回結(jié)果。all的使用場(chǎng)景類似于,玩游戲的時(shí)候,需要提前將游戲需要的資源提前準(zhǔn)備好,才進(jìn)行頁(yè)面的初始化。

5、promise.race方法

race的中文意思為賽跑,也就是說(shuō),看誰(shuí)跑的快,跑的快的就贏了。因此,promise.race也是傳入一個(gè)數(shù)組,但是與promise.all不同的是,race只返回跑的快的值,也就是說(shuō)result返回比較快執(zhí)行的那個(gè)。

var p1 = new Promise(function (resolve) {
 setTimeout(function () {
 console.log(1);
 resolve("第一個(gè)promise");
 }, 3000);
});
var p2 = new Promise(function (resolve) {
 setTimeout(function () {
 console.log(2);
 resolve("第二個(gè)promise");
 }, 1000);
});
Promise.race([p1, p2]).then(function (result) {
 console.log(result); 
});
// 結(jié)果:
// 2
// 第二個(gè)promise
// 1

可以看到,傳的值中,只有p2的返回了,但是p1沒(méi)有停止,依然有執(zhí)行。

race的應(yīng)用場(chǎng)景為,比如我們可以設(shè)置為網(wǎng)路請(qǐng)求超時(shí)。寫兩個(gè)promise,如果在一定的時(shí)間內(nèi)如果成功的那個(gè)我們沒(méi)有執(zhí)行到,我們就執(zhí)行失敗的那個(gè),這里不再舉例子,可以看看阮一峰的ES入門。

以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!

相關(guān)文章

  • JS中this上下文對(duì)象使用方式

    JS中this上下文對(duì)象使用方式

    這篇文章主要為大家詳細(xì)介紹了JS中this上下文對(duì)象使用方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Django模板繼承 extend標(biāo)簽實(shí)例代碼詳解

    Django模板繼承 extend標(biāo)簽實(shí)例代碼詳解

    這篇文章主要介紹了Django模板繼承 extend標(biāo)簽實(shí)例代碼,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-05-05
  • 淺析JS異步加載進(jìn)度條

    淺析JS異步加載進(jìn)度條

    這篇文章主要介紹了JS異步加載進(jìn)度條 的相關(guān)資料,需要的朋友可以參考下
    2016-05-05
  • 淺談js中的this問(wèn)題

    淺談js中的this問(wèn)題

    下面小編就為大家?guī)?lái)一篇淺談js中的this問(wèn)題。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • 原生JavaScript實(shí)現(xiàn)remove()和recover()功能示例

    原生JavaScript實(shí)現(xiàn)remove()和recover()功能示例

    這篇文章主要介紹了原生JavaScript實(shí)現(xiàn)remove()和recover()功能,結(jié)合實(shí)例形式分析了javascript實(shí)現(xiàn)類似jQueryremove()和recover()功能的自定義函數(shù),需要的朋友可以參考下
    2018-07-07
  • canvas學(xué)習(xí)之API整理筆記(一)

    canvas學(xué)習(xí)之API整理筆記(一)

    本文主要介紹了canvas的相關(guān)知識(shí)。canvas本身很簡(jiǎn)單,就是去學(xué)習(xí)它的API,多看實(shí)例,多自己動(dòng)手練習(xí),多總結(jié)。本文介紹了很多小例,具有一定的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2016-12-12
  • 微信小程序?qū)崿F(xiàn)購(gòu)物車頁(yè)面

    微信小程序?qū)崿F(xiàn)購(gòu)物車頁(yè)面

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)購(gòu)物車頁(yè)面,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 利用百度地圖API獲取當(dāng)前位置信息的實(shí)例

    利用百度地圖API獲取當(dāng)前位置信息的實(shí)例

    下面小編就為大家?guī)?lái)一篇利用百度地圖API獲取當(dāng)前位置信息的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧,希望對(duì)大家有所幫助
    2017-11-11
  • 微信小程序開發(fā)之轉(zhuǎn)發(fā)分享功能

    微信小程序開發(fā)之轉(zhuǎn)發(fā)分享功能

    這篇文章主要介紹了微信小程序開發(fā)之轉(zhuǎn)發(fā)分享功能的實(shí)現(xiàn),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-10-10
  • JavaScript設(shè)計(jì)模式之單例模式實(shí)例

    JavaScript設(shè)計(jì)模式之單例模式實(shí)例

    這篇文章主要介紹了JavaScript設(shè)計(jì)模式之單例模式實(shí)例,本文用一個(gè)實(shí)際例子講解JavaScript中的單例模式,需要的朋友可以參考下
    2014-09-09

最新評(píng)論

阿克苏市| 陵川县| 临朐县| 遂平县| 南川市| 临沧市| 孟州市| 临安市| 济南市| 青浦区| 迁安市| 萨迦县| 尼玛县| 莱州市| 靖宇县| 阿克| 峡江县| 晋州市| 习水县| 仪陇县| 苍南县| 紫阳县| 商洛市| 铁岭市| 贺州市| 常德市| 香河县| 五莲县| 东辽县| 保靖县| 淳化县| 山阳县| 巴林右旗| 安阳市| 上思县| 塔城市| 桐庐县| 鄂州市| 河池市| 博兴县| 板桥市|