亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

深入理解Promise.all

2019-11-19 13:18:34
字體:
來源:轉載
供稿:網友

異步之Promise

Promise.all

Promise.all接收的promise數組是按順序執行的還是一起執行的,也就是說返回的結果是順序固定的嗎?

目前有兩種答案:

  1. 應該是同步執行的,但是這樣就有效率問題了,如果想改成異步執行怎么辦呢?
  2. 有些人認為結果是按順序執行的,有些人認為結果順序不確定。

那么我們根據實現來解密:

環境為:

vscode 1.20.1node  v8.9.0npm  v5.6.0

實驗代碼:

// 獲取隨機數,toFixed為四舍五入保留小數,0為保留整數,范圍~1000const getRandom = () => +(Math.random()*1000).toFixed(0);const asyncTask = (taskID) => new Promise( (resolve) => {  // 隨機獲取一次0~1000的隨機數  let timeout = getRandom();  // 打印出傳遞進來的ID號 taskID=1 start.  console.log(`taskID=${taskID} start.`);  // 設置計時時間,function()等價于 () => {...}  setTimeout(function() {    // 打印出執行的taskID,和timeout    console.log(`taskID=${taskID} finished in time=${timeout}.`);    // 異步成功執行    resolve(taskID)  }, timeout);});Promise.all([asyncTask(1),asyncTask(2),asyncTask(3)]).then(resultList => {  console.log('results:',resultList);});

實驗結果如下:

第一次

taskID=1 start.taskID=2 start.taskID=3 start.taskID=2 finished in time=321.taskID=3 finished in time=506.taskID=1 finished in time=932.results:Array(3) [1, 2, 3]

第二次

taskID=1 start.taskID=2 start.taskID=3 start.taskID=1 finished in time=243.taskID=3 finished in time=305.taskID=2 finished in time=792.results:Array(3) [1, 2, 3]

第三次

taskID=1 start.taskID=2 start.taskID=3 start.taskID=3 finished in time=380.taskID=1 finished in time=539.taskID=2 finished in time=782.results:Array(3) [1, 2, 3]

補充知識介紹:

// toFixed() 方法可把 Number 四舍五入為指定小數位數的數字。NumberObject.toFixed(num)// num 必需。規定小數的位數,是 0 ~ 20 之間的值,包括 0 和 // 20,有些實現可以支持更大的數值范圍。如果省略了該參數,將用 0 代替。

Promise構造函數只有一個參數,該參數是一個函數,被稱作執行器,執行器有2個參數,分別是resolve()和reject(),一個表示成功的回調,一個表示失敗的回調。

new Promise(function(resolve, reject) { setTimeout(() => resolve(5), 0)}).then(v => console.log(v)) // 5

記住,Promise實例只能通過resolve或者reject函數來返回,并且使用then()或者catch()獲取,不能在new Promise里面直接return,這樣是獲取不到Promise返回值的。

由此可見,Promise.all 里的任務列表[asyncTask(1),asyncTask(2),asyncTask(3)],我們是按照順序發起的。
但是根據結果來說,它們是異步的,互相之間并不阻塞,每個任務完成時機是不確定的,盡管如此,所有任務結束之
后,它們的結果仍然是按順序地映射到resultList里,這樣就能和Promise.all里的任務列表
[asyncTask(1),asyncTask(2),asyncTask(3)]一一對應起來。

深入理解Promise.all()

可能看到這里有些人沒有清楚,為什么返回一個數組?

我們在來看一下這段代碼:

Promise.all([asyncTask(1),asyncTask(2),asyncTask(3)]).then(resultList => {  console.log('results:',resultList);});

通常我們在使用異步的時候都是只有一個Promise,現在我們使用all()方法包裝多個Promise實例。

語法很簡單:參數只有一個,可迭代對象,可以是數組,或者Symbol類型等。

Promise.all(iterable).then().catch()

傳入3個Promise實例:

Promise.all([ new Promise(function(resolve, reject) {  resolve(1) }), new Promise(function(resolve, reject) {  resolve(2) }), new Promise(function(resolve, reject) {  resolve(3) })]).then(arr => { console.log(arr) // [1, 2, 3]})

那么我們回頭想想應該明白了吧?

因為我們傳入的是數組,那么返回的必須是數組,并且會將講過進行映射。

Promise.race()

語法和all()一樣,但是返回值有所不同,race根據傳入的多個Promise實例,只要有一個實例resolve或者reject,就只返回該結果,其他實例不再執行。

我們簡單看一下例子,返回結果為3,因為我們設置了定時器,第三個Promise執行的最快。

Promise.race([ new Promise(function(resolve, reject) {  setTimeout(() => resolve(1), 1000) }), new Promise(function(resolve, reject) {  setTimeout(() => resolve(2), 100) }), new Promise(function(resolve, reject) {  setTimeout(() => resolve(3), 10) })]).then(value => { console.log(value) // 3})

異步為什么使用箭頭函數

這是我一直困惑的原因,我們將前面的例子進行改造一下。

如下:

const getRandom = () => +(Math.random()*1000).toFixed(0);function test(taskID) { new Promise( (resolve) => {  // 隨機獲取一次0~1000的隨機數  let timeout = getRandom();  // 打印出傳遞進來的ID號  console.log(`taskID=${taskID} start.`);  setTimeout(function() {    console.log(`taskID=${taskID} finished in time=${timeout}.`);    resolve(taskID)  }, timeout);} )}Promise.all([test(1),test(2),test(3)]).then(resultList => {  console.log('results:',resultList);});

我們先來看一下結果是怎樣的?

第一次:

taskID=1 start.taskID=2 start.taskID=3 start.results:Array(3) [undefined, undefined, undefined]taskID=1 finished in time=460.taskID=2 finished in time=704.taskID=3 finished in time=883.

第二次:

taskID=1 start.taskID=2 start.taskID=3 start.results:Array(3) [undefined, undefined, undefined]taskID=2 finished in time=17.taskID=3 finished in time=212.taskID=1 finished in time=612.

第三次:

taskID=1 start.taskID=2 start.taskID=3 start.results:Array(3) [undefined, undefined, undefined]taskID=3 finished in time=130.taskID=1 finished in time=256.taskID=2 finished in time=593.

實驗還是要至少做上3次以上才有說服力。

通過輸出結果我們能夠看出返回的數組內的數據都為undefined。我們就要找出這個原因,那就是找到了為什么要使用箭頭函數。

首先我通過調試來查找

如圖:

程序首先打印出了

taskID=1 start.
taskID=2 start.
taskID=3 start.

說明一定是先執行了

console.log(`taskID=${taskID} start.`);

所以我們在這段打上斷點進行一步一步調試,如下:

根據上圖我們可以看出console.log(taskID=${taskID} start.)每次都會被執行,setTimeout也會被執行,但是3次之后,就會直接開始執行.then(),所以我們找到了原因,Promise.all()這時并沒有等待返回完整的數據就執行了.then(),沒有等到resolve就開始執行了。

說明這里面出現了異常,而這個異常就是由于Promise.all()內的參數,存在函數,造成this混淆,所以我們要使用對象,更準確的說法就是實例。

注意:

以這段代碼為例:

var p1 = Promise.resolve(1),  p2 = Promise.resolve(2),  p3 = Promise.resolve(3);Promise.all([p1, p2, p3]).then(function (results) {  console.log(results); // [1, 2, 3]});

在上面的方法中,promise數組中所有的promise實例都變為resolve的時候,該方法才會返回,并將所有結果傳遞results數組中。promise數組中任何一個promise為reject的話,則整個Promise.all調用會立即終止,并返回一個reject的新的promise對象。reject使用示例如下:

var p1 = Promise.resolve(1),  p2 = Promise.reject(2),  p3 = Promise.resolve(3);Promise.all([p1, p2, p3]).then(function (results) {  //then方法不會被執行  console.log(results); }).catch(function (e){  //catch方法將會被執行,輸出結果為:2  console.log(2);});

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩中文在线不卡| 国产精品久久久久久久久久久久| 91欧美激情另类亚洲| 狠狠躁夜夜躁久久躁别揉| 另类少妇人与禽zozz0性伦| 日韩欧美有码在线| 久久久国产一区| 日韩欧美中文字幕在线播放| 国产区精品视频| 国产精品一区二区久久久| 国产一区二区三区在线观看网站| 日韩av一区二区在线观看| 中文字幕欧美亚洲| 精品久久久香蕉免费精品视频| 亚洲毛片在线免费观看| 亚洲欧美日韩一区二区三区在线| 亚洲精品一区中文字幕乱码| 久久久国产精品亚洲一区| 中文字幕成人在线| 国产精品视频网站| 国产精品永久免费观看| 欧美激情在线一区| 正在播放亚洲1区| 亚洲成人黄色在线| 日本精品视频在线| 久久免费少妇高潮久久精品99| 成人久久精品视频| 国产综合久久久久| 日韩av手机在线观看| 久久99久久99精品中文字幕| 亚洲毛片在线免费观看| 亚洲精品久久久久久久久久久久久| 国产一区玩具在线观看| 日韩中文字幕在线视频| 欧美午夜精品久久久久久浪潮| 欧美一级在线播放| 国产精品欧美激情在线播放| 国产不卡在线观看| 精品久久久久久久久国产字幕| 亚洲欧洲av一区二区| www.欧美免费| 97热精品视频官网| 乱亲女秽乱长久久久| 国产精品久久久久久久久久ktv| 日韩欧亚中文在线| 亚洲一区二区国产| 欧美老女人bb| 青草青草久热精品视频在线网站| 国产欧美精品一区二区| 91精品中文在线| 日韩成人中文字幕| 91久久久国产精品| 国产精品三级久久久久久电影| 欧美性极品xxxx娇小| 欧美精品videos| 亚洲精品国产免费| 日本久久久久久| 成人福利免费观看| 这里只有精品视频在线| 日韩电影免费在线观看| 日韩av日韩在线观看| 国产91热爆ts人妖在线| 欧美最顶级的aⅴ艳星| 国产成人综合一区二区三区| 欧美黄色性视频| 4438全国成人免费| 欧美天天综合色影久久精品| 精品国产一区二区三区四区在线观看| 欧美日韩一区二区三区| 在线电影欧美日韩一区二区私密| 日韩欧美一区二区三区| 青青草原一区二区| 中文字幕日韩专区| 在线电影av不卡网址| 高潮白浆女日韩av免费看| 国内精品久久久久久影视8| 5278欧美一区二区三区| 5566成人精品视频免费| 日韩欧美综合在线视频| 日韩中文字幕视频| 北条麻妃99精品青青久久| 91久久久国产精品| 亚洲v日韩v综合v精品v| 久久久精品2019中文字幕神马| 欧美午夜片在线免费观看| 69久久夜色精品国产69乱青草| 91精品国产沙发| 国产99久久久欧美黑人| 日韩精品在线看| 国产精品老女人视频| 欧美视频免费在线| 亚洲成人黄色在线观看| 欧美久久久精品| 九九热精品视频国产| 久久成人精品视频| 国产综合视频在线观看| 国内精品久久久久久久| 欧美日韩性视频在线| 黑人与娇小精品av专区| 欧美福利小视频| 日韩亚洲欧美中文在线| 中文字幕久热精品视频在线| 亚洲男人天堂2023| 国产精品视频在线观看| 国产成人97精品免费看片| 韩国国内大量揄拍精品视频| 成人性生交大片免费观看嘿嘿视频| 久久精品国产欧美亚洲人人爽| 欧美福利视频网站| 国产视频欧美视频| 一本色道久久88亚洲综合88| 91精品国产91久久| 欧美国产日韩免费| 欧美久久久精品| 欧美精品精品精品精品免费| 久久成人一区二区| 欧美一区三区三区高中清蜜桃| 日韩电影中文字幕在线观看| 久久精品中文字幕| 色综合伊人色综合网| 日韩av片免费在线观看| 国产成人91久久精品| 91情侣偷在线精品国产| 欧美丝袜第一区| 日韩美女在线观看一区| 69久久夜色精品国产69乱青草| 日韩在线观看视频免费| 最近中文字幕mv在线一区二区三区四区| 欧美劲爆第一页| 欧美最猛性xxxxx免费| 亚洲国产免费av| 日韩有码视频在线| 欧美午夜片在线免费观看| 国产欧美日韩高清| 丁香五六月婷婷久久激情| 最近2019年中文视频免费在线观看| 久久精品99久久香蕉国产色戒| 久久精品国产久精国产一老狼| 懂色av一区二区三区| 亚洲japanese制服美女| 亚洲精品久久7777777| 亚洲综合社区网| 日韩av理论片| 欧美另类精品xxxx孕妇| 国产精品免费久久久久影院| 日韩中文字幕精品| 国产va免费精品高清在线| 国产精品黄页免费高清在线观看| 欧美成人亚洲成人日韩成人| 亚洲欧美国产一区二区三区| 国产精品69av| 成人乱人伦精品视频在线观看| 91欧美精品午夜性色福利在线| 亚洲国产精品999| 亚洲色图35p| 国产精品亚洲综合天堂夜夜| 久久精品国产2020观看福利| 日本人成精品视频在线| 中文字幕在线看视频国产欧美| 亚洲欧洲在线视频| 91精品国产综合久久久久久蜜臀| 久久久精品亚洲| 欧美在线观看日本一区| 久久伊人91精品综合网站|