成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Promise使用須知

Tikitoo / 1841人閱讀

摘要:已完成意味著操作成功完成。處理實(shí)例實(shí)例生成以后,可以用方法分別指定狀態(tài)和狀態(tài)的回調(diào)函數(shù)。第二個(gè)回調(diào)函數(shù)在的狀態(tài)變成時(shí)被調(diào)用。方法是的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。具體的使用示例如下情形一全部成功的情況結(jié)果為。

一.關(guān)于Promise

promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案(回調(diào)函數(shù)和事件)更合理和更強(qiáng)大。它由社區(qū)最早提出和實(shí)現(xiàn),ES6將其寫(xiě)進(jìn)了語(yǔ)言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對(duì)象。

所謂Promise,簡(jiǎn)單說(shuō)就是一個(gè)容器,里面保存著某個(gè)未來(lái)才會(huì)結(jié)束的事件(通常是一個(gè)異步操作)的結(jié)果。從語(yǔ)法上說(shuō),Promise 是一個(gè)對(duì)象,從它可以獲取異步操作的消息。Promise 提供統(tǒng)一的 API,各種異步操作都可以用同樣的方法進(jìn)行處理。

它代表一個(gè)異步操作。有三種狀態(tài):

pending(進(jìn)行中): 初始狀態(tài), 初始狀態(tài),未完成或拒絕。

resolved(已完成): 意味著操作成功完成。又名fulfilled。

rejected(已失敗): 意味著操作失敗。

有了Promise,就可以將異步操作以同步操作的流程表達(dá)出,但它也有如下缺點(diǎn)

一旦創(chuàng)建它就會(huì)立即執(zhí)行,無(wú)法中途取消。

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

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

二.應(yīng)用示例 1. 創(chuàng)建Promise
var promise = new Promise(
    /* executor */ 
    function(resolve, reject){
        ...
    }
);

? executor函數(shù)由Promise實(shí)現(xiàn)立即執(zhí)行,傳遞resolve和reject函數(shù). (在Promise構(gòu)造函數(shù)之前調(diào)用執(zhí)行器甚至返回創(chuàng)建的對(duì)象)

? 在?executor?內(nèi)部,promise有如下的狀態(tài)變化可能:

? 1. resolve被調(diào)用,promise由pending變?yōu)閞esolved,代表該P(yáng)romise被成功解析(resolve)

? 2.reject?被調(diào)用,promise由pending變?yōu)閞ejected,代表該P(yáng)romise的值不能用于后續(xù)處理,即被拒絕了

注意:

如果在executor?方法的執(zhí)行過(guò)程中拋出了任何異常,那么promise立即被拒絕(即相當(dāng)于reject方法被調(diào)用),executor?的返回值也就會(huì)被忽略。

如果一個(gè)promise對(duì)象處在resolvedrejected狀態(tài)而不是pending狀態(tài),那么它也可以被稱為settled狀態(tài)。

2.處理Promise實(shí)例

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

promise.then(function(value) {
  // success 狀態(tài)為Resolved時(shí)調(diào)用
}, function(error) {  
  // failure 狀態(tài)為Reject時(shí)調(diào)用
});

then方法可以接受兩個(gè)回調(diào)函數(shù)作為參數(shù)。

第一個(gè)回調(diào)函數(shù):在promise的狀態(tài)變成resolved時(shí)被調(diào)用。它的參數(shù)promise的resolve方法的返回值。

第二個(gè)回調(diào)函數(shù):在promise的狀態(tài)變成rejected時(shí)被調(diào)用。它的參數(shù)promise的reject方法的返回值。且為可選參數(shù)。

catchPromise.prototype.catch方法是.then(null, rejection)的別名,用于指定發(fā)生錯(cuò)誤時(shí)的回調(diào)函數(shù)。

promise.then(function(posts) {
  // ...
}).catch(function(error) {
  console.log("發(fā)生錯(cuò)誤!", error); // 處理 promise 和 前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤
});

擴(kuò)展:

Promise.prototype.then和?Promise.prototype.catch方法返回?promises對(duì)象, 所以它們可以被鏈?zhǔn)秸{(diào)用。但此時(shí)返回的是以函數(shù)返回值生成的新的Promise實(shí)例,不是原來(lái)那個(gè)Promise實(shí)例。

注意問(wèn)題:

Promise 對(duì)象的錯(cuò)誤具有“冒泡”性質(zhì),會(huì)一直向后傳遞,直到被捕獲為止。也就是說(shuō),錯(cuò)誤總是會(huì)被下一個(gè)catch語(yǔ)句捕獲。

3.將多個(gè)Promise實(shí)例,包裝成一個(gè)新的Promise實(shí)例

Promise.all(iterable)?:當(dāng)所有在可迭代參數(shù)中的?promises 已完成,或者第一個(gè)傳遞的?promise(指 reject)失敗時(shí),返回?promise。

var p = Promise.all([p1, p2, p3]);

當(dāng)p1、p2和p3的狀態(tài)均為resolved時(shí)p的狀態(tài)為resolved。

當(dāng)p1、p2或p3中的任意一個(gè)被rejected,p的狀態(tài)就變成rejected,此時(shí)第一個(gè)被reject的實(shí)例的返回值,會(huì)傳遞給p的回調(diào)函數(shù)。

具體的使用示例如下:

情形一:全部成功的情況

Promise.all([Promise.resolve("foo"),Promise.resolve("bar"),Promise.resolve("test")])
  .then(function(result){
            console.log(result); //結(jié)果為:[foo,bar,test]。即所有返回值的數(shù)組。
         })
   .catch(function(error) {
           console.log("error");    //不會(huì)被執(zhí)行
   });

情形二:全部失敗或部分失敗

Promise.all([Promise.resolve("foo"),Promise.reject("barError"),Promise.reject("testError")])
   .then(function(result){
            console.log(result);            //成功回調(diào)  不會(huì)被執(zhí)行
         })
   .catch(function(error) {
           console.log(error);    //結(jié)果為barError或testError。即第一個(gè)被reject的值。
   });

三.常見(jiàn)的使用誤區(qū)

忘記添加 .catch()

通常情況,promise有如下兩種處理方式:

// ------------    不好的寫(xiě)法   -------------
promise.then(function(data) {
    // success
  }, function(err) {   //僅處理promise運(yùn)行時(shí)發(fā)生的錯(cuò)誤。無(wú)法處理回調(diào)中的錯(cuò)誤
    // error
  });

// ------------    好的寫(xiě)法    ------------
promise.then(function(data) {
    // success
}).catch(function(err) {   // 處理 promise 和 前一個(gè)回調(diào)函數(shù)運(yùn)行時(shí)發(fā)生的錯(cuò)誤
    // error 
});

因?yàn)閜romise拋出的錯(cuò)誤不會(huì)傳遞到外層代碼。當(dāng)使用沒(méi)有catch的第一種種寫(xiě)法時(shí),成功回調(diào)的錯(cuò)誤將無(wú)法被處理。因此比較好的方式是,總是使用catch方法。

在then或者catch函數(shù)中不使用return

下面是在是用Promise時(shí),一個(gè)很常見(jiàn)的錯(cuò)誤寫(xiě)法:

//------------    不好的寫(xiě)法    ------------------
promise.then(function?()?{
??getUserInfo(userId);
}).then(function?()?{
  // 在這里可能希望在這個(gè)回調(diào)中使用用戶信息,但你可能會(huì)發(fā)現(xiàn)它根本不存在
});

會(huì)發(fā)生上面的錯(cuò)誤,是因?yàn)閷?duì)Promise的返回及鏈?zhǔn)秸{(diào)用的理解不夠。

每一個(gè)promise都會(huì)給你一個(gè)then()方法(或者catch,它們只是then(null,…)的語(yǔ)法糖)。這里我們是在then()方法的內(nèi)部來(lái)看:

promise.then(function?()?{
??return getUserInfo(userId);
}).then(function?(userInfo)?{
   HadleUser(userInfo);
}).catch(function(error) {
   console.log(error);
});

在回調(diào)中在有三種事可以做:

返回另一個(gè)promise

如果getUserInfo返回一個(gè)Promise,則HadleUser將在該promise變?yōu)閞esolved后執(zhí)行,并以該promise的返回作為入?yún)ⅰ?/p>

返回一個(gè)同步值(或者undefined)

getUserInfo返回一個(gè)同步值,則改值會(huì)被包裝成一個(gè)resolved狀態(tài)的promise,HadleUser將被立刻執(zhí)行,并以getUserInfo返回作為入?yún)ⅰ?/p>

拋出一個(gè)同步錯(cuò)誤

getUserInfo返回一個(gè)同步錯(cuò)誤,則該錯(cuò)誤會(huì)被包裝成一個(gè)rejected狀態(tài)的promise,最終在catch中被捕獲。此時(shí)HadleUser將不會(huì)被執(zhí)行。

promises丟失

你認(rèn)為下面的代碼會(huì)打印出什么?

Promise.resolve("foo").then(Promise.resolve("bar")).then(function?(result)?{
??console.log(result);
});

如果你認(rèn)為打印出bar,那你就大錯(cuò)特錯(cuò)了。它實(shí)際上會(huì)打印出foo。

原因是當(dāng)你給then()傳遞一個(gè)非函數(shù)(比如一個(gè)promise)值的時(shí)候,它實(shí)際上會(huì)解釋為then(null),這會(huì)導(dǎo)致之前的promise的結(jié)果丟失。

四.最佳實(shí)踐總結(jié)

then方法中 永遠(yuǎn)?return?或?throw

如果?promise?鏈中可能出現(xiàn)錯(cuò)誤,一定添加?catch

永遠(yuǎn)傳遞函數(shù)給?then?方法

不要把?promise?寫(xiě)成嵌套

參考鏈接:

Promise -JavaScript | MDN

Promises 很酷,但很多人并沒(méi)有理解就在用了

Promise 對(duì)象

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/82265.html

相關(guān)文章

  • 【容器實(shí)例 Cube】使用須知:秒級(jí)拉起您的業(yè)務(wù)容器提供服務(wù)

    摘要:使用依賴請(qǐng)預(yù)先創(chuàng)建好和子網(wǎng)如果是需要綁定,請(qǐng)預(yù)先給操作賬號(hào)賦予網(wǎng)絡(luò)相關(guān)權(quán)限需要使用到鏡像倉(cāng)庫(kù),需要?jiǎng)?chuàng)建并將鏡像上傳。實(shí)時(shí)文檔歡迎訪問(wèn)使用須知使用須知使用Cube服務(wù),必須通過(guò)UCloud實(shí)名認(rèn)證服務(wù);使用Cube暴露公網(wǎng)服務(wù),請(qǐng)與UCloud備案團(tuán)隊(duì)聯(lián)系進(jìn)行備案,否則可能會(huì)影響您的服務(wù)正常使用;您的業(yè)務(wù)程序已經(jīng)完成容器化,已有Docker鏡像;您創(chuàng)建的Cube實(shí)例,將默認(rèn)鏡像拉取策略為總是(...

    Tecode 評(píng)論0 收藏0
  • 數(shù)據(jù)接口(API)開(kāi)發(fā)須知

    摘要:由服務(wù)端生成在請(qǐng)求任何接口之前,都必須先請(qǐng)求一個(gè)獲取服務(wù)器生成的的接口,獲取之后,才請(qǐng)求其他接口是請(qǐng)求時(shí)間型號(hào)設(shè)備號(hào)系統(tǒng)類(lèi)型加密加密頭部存儲(chǔ)基本參數(shù)加密校驗(yàn)參數(shù)必須填必須填以下為選填,可有可無(wú),任由開(kāi)發(fā)者自己定義類(lèi)型設(shè)備號(hào)版本型號(hào) 傳統(tǒng)API與RESTful API 傳統(tǒng)API 獲取用戶信息 get /api/user/read 更新用戶信息 post /api/user/u...

    piglei 評(píng)論0 收藏0
  • Vert.x入坑須知(3)

    摘要:對(duì)于集成測(cè)試,直接模擬實(shí)際的環(huán)境,再加上合適的,目前看來(lái)也還不錯(cuò)。這里給出兩個(gè)例子集成測(cè)試單元測(cè)試都是基于寫(xiě)的,各位可以體驗(yàn)其酸爽度。好啦,本期內(nèi)容就此結(jié)束,請(qǐng)保持關(guān)注,期待下期繼續(xù)本系列其他文章入坑須知入坑須知 隨著Vert.x進(jìn)化到3.5.0,本系列也迎來(lái)了新篇章。 CORS的新變化 對(duì)于CORS,搞Web開(kāi)發(fā)(不論你是前端,還是后端)的同志應(yīng)該不陌生,尤其是如今微服務(wù)盛行的時(shí)代,...

    CollinPeng 評(píng)論0 收藏0
  • Vert.x入坑須知(4)

    摘要:主要是避免引入太多的復(fù)雜性,并且出于靈活部署的需要。以應(yīng)用為例,由于實(shí)際上是在上執(zhí)行,若它被阻塞,即導(dǎo)致后續(xù)請(qǐng)求全部無(wú)法得到處理。因此,最合適的做法就是對(duì)于簡(jiǎn)單業(yè)務(wù),采用異步庫(kù)。本系列其他文章入坑須知入坑須知入坑須知 最開(kāi)始覺(jué)得這個(gè)系列也就最多3篇了不起了(因?yàn)槭虏贿^(guò)三嘛),沒(méi)曾想居然迎來(lái)了第四篇! Kotlin 由于最近決定投身到區(qū)塊鏈的學(xué)習(xí)當(dāng)中的緣故,出于更好的理解它的基本概念,自...

    summerpxy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Tikitoo

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<