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

資訊專欄INFORMATION COLUMN

JavaScript Promise

Tamic / 2070人閱讀

摘要:前言假如需要向后端發(fā)送一個(gè)請求,并對返回的數(shù)據(jù)進(jìn)行操作,可能我們第一時(shí)間想到的是回調(diào)函數(shù)。如果值本身就是一個(gè)對象,則替代默認(rèn)的對象作為返回值如果值為其他值,則將這個(gè)值作為返回的的函數(shù)的參數(shù)值。

前言

假如需要向后端發(fā)送一個(gè)請求,并對返回的數(shù)據(jù)進(jìn)行操作,可能我們第一時(shí)間想到的是回調(diào)函數(shù)。但如果接著又需要執(zhí)行第二個(gè)、第三個(gè)...第n個(gè)異步操作,那么回調(diào)函數(shù)就會(huì)一層層的嵌套,嚴(yán)重影響了代碼可讀性和可維護(hù)性。

Promise就是解決這個(gè)問題的方案,Promise主要做的事情是把回調(diào)函數(shù)的嵌套邏輯替換成了符合正常人思維習(xí)慣的線性邏輯,本文主要介紹Promise的基本用法、API、鏈?zhǔn)讲僮鳌惓L幚硪约袄胮romise對數(shù)組進(jìn)行異步操作的方法。

一、雜說

Promise是從DOM中的Futures引入javascript的,理由大概是出現(xiàn)了像NodeJs這樣獨(dú)立于瀏覽器之外的JavaScript運(yùn)行環(huán)境。在Promise正式被實(shí)現(xiàn)之前,部分JS庫,像Q、when、WinJS、RSVP.js、jQuery都根據(jù)Promises/A+標(biāo)準(zhǔn)分別實(shí)現(xiàn)了略有差異的”類Promise“對象。如果你的項(xiàng)目中用到了這些庫,不用擔(dān)心,標(biāo)準(zhǔn)的Promise對象提供了將這些”類Promise“對象轉(zhuǎn)換為標(biāo)準(zhǔn)Promise對象的方法(后文會(huì)提到)。關(guān)于Promise的兼容性,參考Can I Use。

Promise有三種狀態(tài):pending、resolved、rejected,狀態(tài)之間的轉(zhuǎn)換只能從pending到resolved或rejected,并且狀態(tài)一旦轉(zhuǎn)換就再也無法改變;

Promise的API:

Promise的構(gòu)造器接受一個(gè)函數(shù),這個(gè)函數(shù)接受兩個(gè)參數(shù):resolved,rejected。

promise.then(onResolved, onRejected), 不做贅述;

promise.catch(onRejected), promise.then(undefined, onRejected)的語法糖。

Promise.resolve(argument),返回一個(gè)Promise對象,具體取決于它接受的參數(shù)類型。

參數(shù)為一個(gè)Promise對象,直接返回這個(gè)對象;

參數(shù)為一個(gè)“類promise”對象,將其轉(zhuǎn)化成真正的Promise對象并返回;

參數(shù)為其他值,返回一個(gè)以參數(shù)值作為其resolved函數(shù)參數(shù)的Promise對象;

Promise.reject(obj), 返回一個(gè)以參數(shù)值(Error的實(shí)例)作為其reject函數(shù)參數(shù)的Promise對象;

Promise.all(array), 參數(shù)值為Promise數(shù)組(也可以包含"類Promise"對象),對數(shù)組的每一項(xiàng)調(diào)用Promise.resolve(),全部成功則resolved并返回返回值的數(shù)組,否則返回第一個(gè)rejected的error對象;

Promise.race(array), 返回?cái)?shù)組中最先resolved或者rejected的那個(gè)Promise對象的返回值或者error對象。

二、基本用法

Promise是一個(gè)JavaScript對象,它執(zhí)行在未來的某個(gè)時(shí)刻才知道結(jié)果的操作并返回得到的值或者失敗的信息。

// Promise is something like this.  
var promise = new Promise(function(resolved, rejected) {
    doSomethingAsync();
 
    if (success) {
        resolved();
    } else {
        rejected();
    }
})

//How to use a promise. First arg is resolved, second is rejected
promise.then(function(res) {
    console.log(res);
}, function(err) {
    alert(err);
})
三、鏈?zhǔn)秸{(diào)用

如果僅有一個(gè)Promise對象的話,情況較為簡單,即在Promise對象被定義時(shí)異步操作就開始執(zhí)行,我們關(guān)心的并不是它什么時(shí)候執(zhí)行完畢,而是要在它執(zhí)行完或者返回錯(cuò)誤后對結(jié)果進(jìn)行處理。但當(dāng)多個(gè)Promise要按照一定的順序執(zhí)行時(shí),事情就變得復(fù)雜起來了。

function fetchSomething() {
    return new Promise(function(resolved) {
        if (success) {
            resolved(res);
        }
    });
}
fetchSomething().then(function(res) {
    console.log(res);
    return fetchSomething();
}).then(function(res) {
    console.log("duplicate res");
    return "done";
}).then(function(tip) {
    console.log(tip);
})

then函數(shù)始終返回一個(gè)promise對象,后續(xù)的then要等待返回的promise resolve后才能執(zhí)行,這樣就實(shí)現(xiàn)了線性邏輯的鏈?zhǔn)秸{(diào)用。而返回的promise取決于then函數(shù)本身return的值。如果return值本身就是一個(gè)promise對象,則替代默認(rèn)的promise對象作為返回值;如果return值為其他值,則將這個(gè)值作為返回的promise的resolve函數(shù)的參數(shù)值。

四、異常處理

從上面的代碼可以看出,then函數(shù)接受兩個(gè)參數(shù):resolved、rejected。上面沒寫rejected是因?yàn)閞ejected函數(shù)是可選的,當(dāng)然也可以在then之后寫catch,.catch(rejected)本質(zhì)上是.then(undefined, rejected)的語法糖。
這兩種方式是有區(qū)別的,.then(resolved, rejected)只能捕獲之前的promise的異常,而寫在其后的.catch(undefined, rejected)還可以捕獲其resolved函數(shù)產(chǎn)生的異常。另外只要Promise鏈中有一個(gè)promise對象拋出異常,其后所有的resolved都被跳過,直到這個(gè)異常被rejected或者catch處理。

五、排序

當(dāng)需要用數(shù)組的數(shù)據(jù)執(zhí)行異步操作,因?yàn)閿?shù)組的遍歷方法forEach、map等都是同步的,所以結(jié)果的順序就取決于異步操作完成的順序,如果對順序有要求,這樣就不盡人意。

// 假設(shè)fetchID返回一個(gè)Promise對象
names.forEach(function(name) {
    fetchID(name).then(function(id) {
        renderInfo(id);
    })
})

這個(gè)時(shí)候就需要利用then()來制定順序:

names.reduce(function(sequence, name) {
    return sequence.then(function() {
        return fetchID(name);
    }).then(function(id) {
        renderID(id);
    })
}, Promise.then())

因?yàn)榇藭r(shí)先遍歷的name處理的結(jié)果將作為后面的sequence,構(gòu)成了鏈?zhǔn)疥P(guān)系,就避免了下載速度決定順序的問題。但仍然可以優(yōu)化:因?yàn)榇藭r(shí)的ID是獲取一個(gè),render一個(gè)的。如果能夠先獲取所有的ID再逐條渲染的話,性能會(huì)更好。

Promise.all(names.map(fetchID))
       .then(function(IDs) {
           IDS.forEach(function(id) {
               renderID(id);    //同步
           })
       })

參考文章:
JavaScript Promises: an Introduction (自備梯子)
Master the JavaScript Interview: What is a Promise? (自備梯子)

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

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

相關(guān)文章

  • JavaScript引擎是如何工作的?從調(diào)用棧到Promise你需要知道的一切

    摘要:最受歡迎的引擎是,在和中使用,用于,以及所使用的。怎么處理每個(gè)引擎都有一個(gè)基本組件,稱為調(diào)用棧。也就是說,如果有其他函數(shù)等待執(zhí)行,函數(shù)是不能離開調(diào)用棧的。每個(gè)異步函數(shù)在被送入調(diào)用棧之前必須通過回調(diào)隊(duì)列。例如方法是在中傳遞的回調(diào)函數(shù)。 ? 翻譯:瘋狂的技術(shù)宅 原文:www.valentinog.com/blog/engine… 從Call Stack,Global Me...

    zzbo 評論0 收藏0
  • JavaScript 異步

    摘要:從最開始的到封裝后的都在試圖解決異步編程過程中的問題。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。寫一個(gè)符合規(guī)范并可配合使用的寫一個(gè)符合規(guī)范并可配合使用的理解的工作原理采用回調(diào)函數(shù)來處理異步編程。 JavaScript怎么使用循環(huán)代替(異步)遞歸 問題描述 在開發(fā)過程中,遇到一個(gè)需求:在系統(tǒng)初始化時(shí)通過http獲取一個(gè)第三方服務(wù)器端的列表,第三方服務(wù)器提供了一個(gè)接口,可通過...

    tuniutech 評論0 收藏0
  • JavaScript引擎是如何工作的?從調(diào)用棧到Promise你需要知道的一切

    摘要:最受歡迎的引擎是,在和中使用,用于,以及所使用的。單線程的我們說是單線程的,因?yàn)橛幸粋€(gè)調(diào)用棧處理我們的函數(shù)。也就是說,如果有其他函數(shù)等待執(zhí)行,函數(shù)是不能離開調(diào)用棧的。每個(gè)異步函數(shù)在被送入調(diào)用棧之前必須通過回調(diào)隊(duì)列。 翻譯:瘋狂的技術(shù)宅原文:https://www.valentinog.com/bl... 本文首發(fā)微信公眾號:前端先鋒歡迎關(guān)注,每天都給你推送新鮮的前端技術(shù)文章 sh...

    Simon_Zhou 評論0 收藏0
  • ES6-7

    摘要:的翻譯文檔由的維護(hù)很多人說,阮老師已經(jīng)有一本關(guān)于的書了入門,覺得看看這本書就足夠了。前端的異步解決方案之和異步編程模式在前端開發(fā)過程中,顯得越來越重要。為了讓編程更美好,我們就需要引入來降低異步編程的復(fù)雜性。 JavaScript Promise 迷你書(中文版) 超詳細(xì)介紹promise的gitbook,看完再不會(huì)promise...... 本書的目的是以目前還在制定中的ECMASc...

    mudiyouyou 評論0 收藏0
  • 異步 JavaScriptPromise

    摘要:為這些回調(diào)函數(shù)分別命名并分離存放可以在形式上減少嵌套,使代碼清晰,但仍然不能解決問題。如果在一個(gè)結(jié)束成功或失敗,同前面的說明后,添加針對成功或失敗的回調(diào),則回調(diào)函數(shù)會(huì)立即執(zhí)行。 異步? 我在很多地方都看到過異步(Asynchronous)這個(gè)詞,但在我還不是很理解這個(gè)概念的時(shí)候,卻發(fā)現(xiàn)自己常常會(huì)被當(dāng)做已經(jīng)很清楚(* ̄? ̄)。 如果你也有類似的情況,沒關(guān)系,搜索一下這個(gè)詞,就可以得到大致...

    livem 評論0 收藏0
  • javascript異步之Promise.all()、Promise.race()、Promise.

    摘要:的執(zhí)行與狀態(tài)無關(guān)當(dāng)?shù)玫綘顟B(tài)不論成功或失敗后就會(huì)執(zhí)行,原文鏈接參考鏈接對象 同期異步系列文章推薦談一談javascript異步j(luò)avascript異步中的回調(diào)javascript異步與promisejavascript異步之Promise.resolve()、Promise.reject()javascript異步之Promise then和catchjavascript異步之a(chǎn)sync...

    clasnake 評論0 收藏0

發(fā)表評論

0條評論

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