亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入理解Promise.all

 更新時(shí)間:2018年08月08日 14:55:52   作者:FlyWine  
這篇文章主要介紹了深入理解Promise.all,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧

異步之Promise

Promise.all

Promise.all接收的promise數(shù)組是按順序執(zhí)行的還是一起執(zhí)行的,也就是說(shuō)返回的結(jié)果是順序固定的嗎?

目前有兩種答案:

  1. 應(yīng)該是同步執(zhí)行的,但是這樣就有效率問(wèn)題了,如果想改成異步執(zhí)行怎么辦呢?
  2. 有些人認(rèn)為結(jié)果是按順序執(zhí)行的,有些人認(rèn)為結(jié)果順序不確定。

那么我們根據(jù)實(shí)現(xiàn)來(lái)解密:

環(huán)境為:

vscode 1.20.1
node  v8.9.0
npm  v5.6.0

實(shí)驗(yàn)代碼:

// 獲取隨機(jī)數(shù),toFixed為四舍五入保留小數(shù),0為保留整數(shù),范圍~1000
const getRandom = () => +(Math.random()*1000).toFixed(0);

const asyncTask = (taskID) => new Promise( (resolve) => {
  // 隨機(jī)獲取一次0~1000的隨機(jī)數(shù)
  let timeout = getRandom();
  // 打印出傳遞進(jìn)來(lái)的ID號(hào) taskID=1 start.
  console.log(`taskID=${taskID} start.`);
  // 設(shè)置計(jì)時(shí)時(shí)間,function()等價(jià)于 () => {...}
  setTimeout(function() {
    // 打印出執(zhí)行的taskID,和timeout
    console.log(`taskID=${taskID} finished in time=${timeout}.`);
    // 異步成功執(zhí)行
    resolve(taskID)
  }, timeout);
});

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

實(shí)驗(yàn)結(jié)果如下:

第一次

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]

補(bǔ)充知識(shí)介紹:

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

Promise構(gòu)造函數(shù)只有一個(gè)參數(shù),該參數(shù)是一個(gè)函數(shù),被稱作執(zhí)行器,執(zhí)行器有2個(gè)參數(shù),分別是resolve()和reject(),一個(gè)表示成功的回調(diào),一個(gè)表示失敗的回調(diào)。

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

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

由此可見(jiàn),Promise.all 里的任務(wù)列表[asyncTask(1),asyncTask(2),asyncTask(3)],我們是按照順序發(fā)起的。
但是根據(jù)結(jié)果來(lái)說(shuō),它們是異步的,互相之間并不阻塞,每個(gè)任務(wù)完成時(shí)機(jī)是不確定的,盡管如此,所有任務(wù)結(jié)束之
后,它們的結(jié)果仍然是按順序地映射到resultList里,這樣就能和Promise.all里的任務(wù)列表
[asyncTask(1),asyncTask(2),asyncTask(3)]一一對(duì)應(yīng)起來(lái)。

深入理解Promise.all()

可能看到這里有些人沒(méi)有清楚,為什么返回一個(gè)數(shù)組?

我們?cè)趤?lái)看一下這段代碼:

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

通常我們?cè)谑褂卯惒降臅r(shí)候都是只有一個(gè)Promise,現(xiàn)在我們使用all()方法包裝多個(gè)Promise實(shí)例。

語(yǔ)法很簡(jiǎn)單:參數(shù)只有一個(gè),可迭代對(duì)象,可以是數(shù)組,或者Symbol類型等。

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

傳入3個(gè)Promise實(shí)例:

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]
})

那么我們回頭想想應(yīng)該明白了吧?

因?yàn)槲覀儌魅氲氖菙?shù)組,那么返回的必須是數(shù)組,并且會(huì)將講過(guò)進(jìn)行映射。

Promise.race()

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

我們簡(jiǎn)單看一下例子,返回結(jié)果為3,因?yàn)槲覀冊(cè)O(shè)置了定時(shí)器,第三個(gè)Promise執(zhí)行的最快。

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
})

異步為什么使用箭頭函數(shù)

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

如下:

const getRandom = () => +(Math.random()*1000).toFixed(0);

function test(taskID) {
 new Promise( (resolve) => {
  // 隨機(jī)獲取一次0~1000的隨機(jī)數(shù)
  let timeout = getRandom();
  // 打印出傳遞進(jìn)來(lái)的ID號(hào)
  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);
});

我們先來(lái)看一下結(jié)果是怎樣的?

第一次:

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.

實(shí)驗(yàn)還是要至少做上3次以上才有說(shuō)服力。

通過(guò)輸出結(jié)果我們能夠看出返回的數(shù)組內(nèi)的數(shù)據(jù)都為undefined。我們就要找出這個(gè)原因,那就是找到了為什么要使用箭頭函數(shù)。

首先我通過(guò)調(diào)試來(lái)查找

如圖:

程序首先打印出了

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

說(shuō)明一定是先執(zhí)行了

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

所以我們?cè)谶@段打上斷點(diǎn)進(jìn)行一步一步調(diào)試,如下:

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

說(shuō)明這里面出現(xiàn)了異常,而這個(gè)異常就是由于Promise.all()內(nèi)的參數(shù),存在函數(shù),造成this混淆,所以我們要使用對(duì)象,更準(zhǔn)確的說(shuō)法就是實(shí)例。

注意:

以這段代碼為例:

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數(shù)組中所有的promise實(shí)例都變?yōu)閞esolve的時(shí)候,該方法才會(huì)返回,并將所有結(jié)果傳遞results數(shù)組中。promise數(shù)組中任何一個(gè)promise為reject的話,則整個(gè)Promise.all調(diào)用會(huì)立即終止,并返回一個(gè)reject的新的promise對(duì)象。reject使用示例如下:

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

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • swiper.js插件實(shí)現(xiàn)pc端文本上下滑動(dòng)功能示例

    swiper.js插件實(shí)現(xiàn)pc端文本上下滑動(dòng)功能示例

    這篇文章主要介紹了swiper.js插件實(shí)現(xiàn)pc端文本上下滑動(dòng)功能,結(jié)合實(shí)例形式分析了swiper.js插件的具體引用與相關(guān)使用技巧,需要的朋友可以參考下
    2018-12-12
  • javascript引用類型之時(shí)間Date和數(shù)組Array

    javascript引用類型之時(shí)間Date和數(shù)組Array

    引用類型的值(對(duì)象)其實(shí)就是引用類型的一個(gè)實(shí)例,接下來(lái),通過(guò)本篇文章給大家介紹javascript引用類型之時(shí)間Date和數(shù)組Array,需要的朋友可以參考下
    2015-08-08
  • JS 常用校驗(yàn)函數(shù)

    JS 常用校驗(yàn)函數(shù)

    比較常用到的一些字符驗(yàn)證函數(shù),里面有正則等好東西,推薦大家保存即可直接調(diào)用。
    2009-03-03
  • JS寫XSS cookie stealer來(lái)竊取密碼的步驟詳解

    JS寫XSS cookie stealer來(lái)竊取密碼的步驟詳解

    JavaScript是web中最常用的腳本開(kāi)發(fā)語(yǔ)言,js可以自動(dòng)執(zhí)行站點(diǎn)組件,管理站點(diǎn)內(nèi)容,在web業(yè)內(nèi)實(shí)現(xiàn)其他有用的函數(shù)。這篇文章主要介紹了JS寫XSS cookie stealer來(lái)竊取密碼的步驟詳解,需要的朋友可以參考下
    2017-11-11
  • 詳解如何編寫一個(gè)Typescript的類型聲明文件

    詳解如何編寫一個(gè)Typescript的類型聲明文件

    我們知道TypeScript根據(jù)類型聲明進(jìn)行類型檢查,但有些情況可能沒(méi)有類型聲明,這個(gè)時(shí)候就需要我們自己寫一個(gè),下面小編就來(lái)和大家聊聊如果寫一個(gè)Typescript的類型聲明文件呢
    2023-06-06
  • 基于Turn.js 實(shí)現(xiàn)翻書效果實(shí)例解析

    基于Turn.js 實(shí)現(xiàn)翻書效果實(shí)例解析

    最近項(xiàng)目經(jīng)理我個(gè)項(xiàng)目練練手,其項(xiàng)目需求是要實(shí)現(xiàn)翻書效果,看到這個(gè)需求后,我真是懵了,這咋整,我可是java出身的啊,這個(gè)問(wèn)題真是難住我了,后來(lái)有同事的指導(dǎo),問(wèn)題順利解決,下面小編把學(xué)習(xí)心得分享,感興趣的朋友可以參考下
    2016-06-06
  • 微信小程序 image組件遇到的問(wèn)題

    微信小程序 image組件遇到的問(wèn)題

    這篇文章主要介紹了微信小程序 image組件遇到的問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-05-05
  • js常用方法示例梳理(總結(jié)篇)

    js常用方法示例梳理(總結(jié)篇)

    這篇文章主要為大家介紹了js常用的方法示例梳理總結(jié)及功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 22種JavaScript中數(shù)組常用API總結(jié)

    22種JavaScript中數(shù)組常用API總結(jié)

    在前端開(kāi)發(fā)中,數(shù)組是一種常見(jiàn)且重要的數(shù)據(jù)結(jié)構(gòu),本文主要介紹了前端中數(shù)組常用的API,包括添加、刪除、截取、合并、轉(zhuǎn)換等操作,希望對(duì)大家有所幫助
    2023-05-05
  • JS實(shí)現(xiàn)帶鼠標(biāo)效果的頭像及文章列表代碼

    JS實(shí)現(xiàn)帶鼠標(biāo)效果的頭像及文章列表代碼

    這篇文章主要介紹了JS實(shí)現(xiàn)帶鼠標(biāo)效果的頭像及文章列表代碼,涉及JavaScript響應(yīng)鼠標(biāo)事件動(dòng)態(tài)切換頁(yè)面元素樣式的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-09-09

最新評(píng)論