js異步處理方案之異步串行與異步并行
js異步處理方案,js的異步串行與異步并行
一、什么是串行,并行,并發(fā)
串行:這個(gè)就像隊(duì)列一樣,一個(gè)執(zhí)行完,下一個(gè)再執(zhí)行,比如js同步執(zhí)行
并發(fā):是指這個(gè)系統(tǒng)擁有處理多個(gè)任務(wù)的能力,在一定時(shí)間發(fā)出,不需要同時(shí)性執(zhí)行。js的異步消息隊(duì)列讓js擁有并發(fā)的能力
? 比如執(zhí)行多個(gè)settimeout 它會(huì)掛載在消息隊(duì)列,然后依次執(zhí)行
并行:是指這個(gè)系統(tǒng)擁同時(shí)處理多個(gè)任務(wù)的能力,屬于多線程的一種方式,而js是屬于單線程 雖然可以通過(guò)worker來(lái)創(chuàng)建多線程,但是子線程
? 完全受主線程控制,沒(méi)有改變JavaScript單線程的本質(zhì)
串行示意圖:

有人會(huì)問(wèn),異步不是都在消息隊(duì)列嗎,不就是一個(gè)一個(gè)執(zhí)行了嗎?
舉個(gè)例子,如果本身就是串行執(zhí)行,那么你現(xiàn)在執(zhí)行2給個(gè)任務(wù),一個(gè)是5秒后打印console.log(1),一個(gè)是十秒后打印console.log(2)
按照串行應(yīng)該是15秒執(zhí)行完畢,但實(shí)際耗時(shí)是10秒,如上這是并發(fā),
console.time()
setTimeout(() => {
console.log(1)
}, 5000);
setTimeout(() => {
console.log(2)
console.timeEnd()
}, 10000);

二、實(shí)現(xiàn)異步串行
大多時(shí)候我們可以用 promise 和async await來(lái)解決
promise
比較少的時(shí)候,可以用.then來(lái)實(shí)現(xiàn)串行
var a = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
consloe.log('a')
resolve('a')
}, 3000)
})
}
var b = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
consloe.log('b')
resolve('b')
}, 2000)
})
};
console.time('test')
a().then((aa) => {
b().then((bb) => {
console.log(`${aa}-${bb}`)
console.timeEnd('test')
})
})
async await
我們改造一下,明顯使用await看起來(lái)更加清晰
var a = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
consloe.log('a')
resolve('a')
}, 3000)
})
}
var b = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
consloe.log('b')
resolve('b')
}, 2000)
})
};
(async () => {
console.time('test')
var aa = await a()
var bb = await b()
console.log(`${aa}-${bb}`)
console.timeEnd('test')
})()
但當(dāng)我們有多個(gè)異步,比如2000個(gè)該如何
var createPromise = function(time) {
// then中的回調(diào)函數(shù)
return (resolve, reject) => {
return new Promise((resolve, reject) => {
setTimeout(() => { //模擬請(qǐng)求 (真實(shí)使用把time設(shè)置為0,將resolve傳入異步函數(shù)中)
console.log('timein' + time)
resolve(); //在異步處理結(jié)束后resolve
}, time * 1000)
})
}
}
var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)];
function serpromise(arr) {
arr.reduce((pre, next, index, carr) => {
return pre.then(next)
}, Promise.resolve())
}
// 相當(dāng)于
// Promise.resolve().then(createPromise(2)).then(createPromise(1))......
serpromise(arr)
async await
var createPromise = function(time) {
return () => {
return new Promise((resolve, reject) => {
setTimeout(() => { //模擬請(qǐng)求 (真實(shí)使用把time設(shè)置為0,將resolve傳入異步函數(shù)中)
console.log('timein' + time)
resolve(); //在異步處理結(jié)束后resolve
}, time * 1000)
})
}
}
var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)];
var fn = async function(promiseArr) {
for (let i = 0, len = arr.length; i < len; i++) {
let currentPromise = promiseArr[i]
var result = await currentPromise()
}
}
fn(arr)
通過(guò)打印可以看出如過(guò)是并發(fā)的打印會(huì)是1,2,3,4,5

三、實(shí)現(xiàn)異步并行
并行示意圖:

js并不能并行,我們只是可以思考如何卡在abc都執(zhí)行完成,這里可以用promise.all 來(lái)輕松實(shí)現(xiàn)
const a = new Promise((resolve, reject) => {
//模擬異步任務(wù)
setTimeout(function() {
resolve('a');
}, 1000)
})
.then(result => result)
.catch(e => {
})
const b = new Promise((resolve, reject) => {
setTimeout(function() {
// resolve('b');
reject('Error in b');
}, 1000)
})
.then(result => result)
.catch(e => e)
Promise.all([a, b]).then(data => {
console.log('data', data)
})
.catch(e => console.log('erro', e));
這里需要注意的是,all能接受的 resolve reject都行,所以需要每個(gè)自己去處理異常
多個(gè)異步
promise
var createPromise = function(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('time', time);
resolve(time)
}, time * 1000)
})
}
var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)];
Promise.all(arr).then(data => {
console.log('data', data)
})
asnyc await
var createPromise = function(time) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('time', time);
resolve(time)
}, time * 1000)
})
}
var arr = [createPromise(2), createPromise(3), createPromise(1), createPromise(4), createPromise(5)];
var fn = async function(promiseArr) {
let awaitArr = []
for (let i = 0, len = arr.length; i < len; i++) {
let currentPromise = promiseArr[i]
let result = await currentPromise
awaitArr.push(result)
}
return awaitArr
}
// async 返回的是一個(gè)promise
fn(arr).then(data => {
console.log('data', data);
})

到此這篇關(guān)于js異步處理方案,js的異步串行與異步并行的文章就介紹到這了,更多相關(guān)js異步處理內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript replace(rgExp,fn)正則替換的用法
再看jQuery源碼的時(shí)候遇到了replace中參數(shù)為函數(shù)的用法,正好復(fù)習(xí)一下replace正則替換的用法。2010-03-03
深入解析JavaScript中的arguments對(duì)象
arguments是JavaScript里的一個(gè)內(nèi)置對(duì)象,像數(shù)組結(jié)構(gòu)一樣存儲(chǔ)參數(shù)的傳遞,這里我們就來(lái)深入解析JavaScript中的arguments對(duì)象,需要的朋友可以參考下2016-06-06
Javascript標(biāo)準(zhǔn)DOM Range操作全集
Javascript標(biāo)準(zhǔn)DOM Range操作全集...2007-01-01
分享javascript實(shí)現(xiàn)的冒泡排序代碼并優(yōu)化
本文給大家匯總介紹了幾個(gè)個(gè)人收藏的JavaScript實(shí)現(xiàn)冒泡排序的代碼,都是非常的不錯(cuò),有需要的小伙伴可以參考下2016-06-06
JavaScript中數(shù)組繼承的簡(jiǎn)單示例
這篇文章主要介紹了JavaScript中數(shù)組繼承的簡(jiǎn)單示例,數(shù)組繼承是JavaScript入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-07-07
javascript定義變量時(shí)加var與不加var的區(qū)別
這篇文章主要介紹了javascript 變量中 var 與不加var的區(qū)別,需要的朋友可以參考下2014-12-12
JavaScript必知必會(huì)(七)js對(duì)象繼承
這篇文章主要介紹了JavaScript必知必會(huì)(七)js對(duì)象繼承的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-06-06

