您好,登錄后才能下訂單哦!
本篇內容主要講解“js怎么實現異步串行與異步并行”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“js怎么實現異步串行與異步并行”吧!
串行:這個就像隊列一樣,一個執行完,下一個再執行,比如js同步執行
并發:是指這個系統擁有處理多個任務的能力,在一定時間發出,不需要同時性執行。js的異步消息隊列讓js擁有并發的能力
比如執行多個settimeout 它會掛載在消息隊列,然后依次執行
并行:是指這個系統擁同時處理多個任務的能力,屬于多線程的一種方式,而js是屬于單線程 雖然可以通過worker來創建多線程,但是子線程
完全受主線程控制,沒有改變JavaScript單線程的本質
串行示意圖:
有人會問,異步不是都在消息隊列嗎,不就是一個一個執行了嗎?
舉個例子,如果本身就是串行執行,那么你現在執行2給個任務,一個是5秒后打印console.log(1),一個是十秒后打印console.log(2)
按照串行應該是15秒執行完畢,但實際耗時是10秒,如上這是并發,
console.time() setTimeout(() => { console.log(1) }, 5000); setTimeout(() => { console.log(2) console.timeEnd() }, 10000);
大多時候我們可以用 promise 和async await來解決
promise
比較少的時候,可以用.then來實現串行
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看起來更加清晰
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') })()
但當我們有多個異步,比如2000個該如何
var createPromise = function(time) { // then中的回調函數 return (resolve, reject) => { return new Promise((resolve, reject) => { setTimeout(() => { //模擬請求 (真實使用把time設置為0,將resolve傳入異步函數中) console.log('timein' + time) resolve(); //在異步處理結束后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()) } // 相當于 // Promise.resolve().then(createPromise(2)).then(createPromise(1))...... serpromise(arr)
async await
var createPromise = function(time) { return () => { return new Promise((resolve, reject) => { setTimeout(() => { //模擬請求 (真實使用把time設置為0,將resolve傳入異步函數中) console.log('timein' + time) resolve(); //在異步處理結束后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)
通過打印可以看出如過是并發的打印會是1,2,3,4,5
并行示意圖:
js并不能并行,我們只是可以思考如何卡在abc都執行完成,這里可以用promise.all 來輕松實現
const a = new Promise((resolve, reject) => { //模擬異步任務 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都行,所以需要每個自己去處理異常
多個異步
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 返回的是一個promise fn(arr).then(data => { console.log('data', data); })
到此,相信大家對“js怎么實現異步串行與異步并行”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。