JS 中實現(xiàn)一個串型異步函數(shù)隊列
背景
在日常業(yè)務(wù)開發(fā)中,總會遇到這種場景,有一串請求,下一個請求依賴上一個異步請求的結(jié)果,一般來說,我在處理這種需求的時候使用 async/await 。但是在某些情況(比如面試),可能需要提供更加高級的解決方案。
通常解法
async/await 串型請求
// 生成異步請求函數(shù)
/*
@param {boolean} isSuccess 是否成功
@param {number} delay 請求返回時間
@return {Promise} promise
*/
function genAsyncTask(isSuccess, delay) {
return (params) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
isSuccess ? resolve(params || 'success') : reject('error')
}, delay)
})
}
}
// 異步請求
const asyncTask1 = genAsyncTask(true, 1000)
const asyncTask2 = genAsyncTask(true, 2000)
const asyncTask3 = genAsyncTask(true, 3000)
// 通常解法
;(async()=>{
let result1 = await asyncTask1('a')
let result2 = await asyncTask2(result1)
await asyncTask3(result2)
// ...
})()for...of 解法
不依賴上次結(jié)果,只要求順序執(zhí)行時,注意和Promise.all()區(qū)別
const asyncTasks = [asyncTask3, asyncTask2, asyncTask1]
;(async()=>{
for(task of asyncTasks){
console.log(await task())
}
})()
// 輸出:success 3s之后
// 輸出:success 再2s之后
// 輸出:success 再1s之后需求一
- 實現(xiàn) queuePromsies 方法
- 入?yún)楫惒秸埱蠛瘮?shù)數(shù)組
- 上個結(jié)果作為下個異步函數(shù)的入?yún)?/li>
reduce 實現(xiàn)
/* reduce
@param {array} promises 異步請求函數(shù)數(shù)組 note: 傳入異步函數(shù),它返回 promise。而不是傳入 promise 對象。
@initInput (any) initInput 初始參數(shù),作為 reduce 初始值參數(shù)
*/
function queuePromises(asyncTasks, initInput = 'initInput') {
return asyncTasks.reduce(
(preAsyncTask, curAsyncTask) =>
preAsyncTask.then((result) => {
return curAsyncTask(result)
}),
Promise.resolve(initInput)
)
}
/* 測試用例 */
;(async () => {
try {
let result = await queuePromises([asyncTask1, asyncTask2, asyncTask3])
console.log(result)
} catch (error) {
console.log('error', error)
}
})()
// 輸出:initInput需求二
- 實現(xiàn) chainPromise 函數(shù)
- 不使用 async / await 語法
- 實現(xiàn)單個 promise 失敗后重新執(zhí)行的配置,即 promise 失敗后允許繼續(xù)嘗試發(fā)送幾次請求,重傳次數(shù)用完則認為失敗,進入 catch
遞歸實現(xiàn)
// 遞歸解法
function chainPromise(tasks, { limit } = { limit: 3 }) {
const results = []
let tryTimes = 1
let index = 0
function next() {
const task = tasks[index]
if (task) {
return task().then(
(result) => {
tryTimes = 1
index++
results.push(result)
return next()
},
(reason) => {
if (tryTimes <= limit) {
console.log('try!!!', tryTimes)
tryTimes++
return next()
} else {
throw new Error('limit more than 3')
}
}
)
} else {
return Promise.resolve(results)
}
}
return next()
}
chainPromise([asyncTask1, asyncTask2, asyncTask3]), {limit:3}]).then(console.log)
// [1000,2000,3000]到此這篇關(guān)于JS 中實現(xiàn)一個串型異步函數(shù)隊列的文章就介紹到這了,更多相關(guān)JS串型異步函數(shù)隊列內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript中number轉(zhuǎn)換成string介紹
這篇文章主要介紹了JavaScript中number轉(zhuǎn)換成string介紹,本文講解了4個把number轉(zhuǎn)換成string的函數(shù),需要的朋友可以參考下2014-12-12
快速理解 JavaScript 中的 LHS 和 RHS 查詢的用法
本篇文章主要介紹了快速理解 JavaScript 中的 LHS 和 RHS 查詢的用法,有一定的參考價值,感興趣的小伙伴們可以參考一下2017-08-08
echart簡介_動力節(jié)點Java學(xué)院整理
這篇文章主要介紹了echart簡介,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
JS獲取及設(shè)置TextArea或input文本框選擇文本位置的方法
這篇文章主要介紹了JS獲取及設(shè)置TextArea或input文本框選擇文本位置的方法,涉及TextArea及input文本操作技巧,需要的朋友可以參考下2015-03-03
兼容FireFox 用javascript寫的一個畫圖函數(shù)
兼容FireFox 用javascript寫的一個畫圖函數(shù)...2007-08-08
JavaScript 以對象為索引的關(guān)聯(lián)數(shù)組
我們常說JavaScript原生支持json,因為我們可以認為json就是對JavaScript的Object對象的靈活應(yīng)用。2010-05-05

