想要一个Promise.queue,类似Promise.all,接受一个装了很多个promise对象的数组,但逐个依次决议(不像all一样是并发的,这里想要的是串行一个接一个的完成决议),获得一个结果数组,不考虑参数传递,google了一些答案,感觉都不太满意,求教大家,谢谢
想要一个Promise.queue,类似Promise.all,接受一个装了很多个promise对象的数组,但逐个依次决议(不像all一样是并发的,这里想要的是串行一个接一个的完成决议),获得一个结果数组,不考虑参数传递,google了一些答案,感觉都不太满意,求教大家,谢谢
接受一个装了很多个promise对象的数组,但逐个一次执行
,你仔细想一下,在JS里面什么是可执行的?Promise
?
事实上能够被执行
的只有函数,所以我理解的是:你的入参应该是一个函数数组,每个函数都会返回一个Promise
只有在这个Promise
被resolve
,或者reject
之后,其后面的一个函数才会被执行。如果是这样的话就很简单了:
function executeWaterfall<T>(...executors: Array<() => T|Promise<T>>): Promise<T[]> {
const output: T[] = []
let p: Promise<T> = Promise.resolve<T>(void 0)
for (const executor of executors) {
p = p.then(executor).then((data) => output.push(data))
}
return p.then(() => output)
}
// 用例
executeWaterfall<number>(
() => 0,
() => new Promise((resolve) => setTimeout(() => resolve(1), 1e3)),
() => Promise.resolve(2),
).then((output) => {
console.log(output) // [0, 1, 2]
})
这里面没有考虑reject
的情况:如果中间任何一个函数reject
了,则返回会被reject
。
容我安利 promise的队列模块,支持设置并发,重试次数,超时时间
promise-queue-plus
var Queue = require('promise-queue-plus');
var q = Queue.Promise; //a Promise utils;
//Realize a queue with a maximum concurrency of 1
var queue1 = new Queue(1,{
"retry":0 //Number of retries
,"retryIsJump":false //retry now?
,"timeout":0 //The timeout period
});
//a return promise function
function testfn(i){
return new Promise(function(resolve,reject){
setTimeout(function(){
resolve(i)
},300)
})
}
var log = function(msg){ console.log(msg); }
queue1.push(testfn,[1]) //add job (FIFO)
.then(log);
queue1.push(function(){return 2;}) //The normal function returns a promise according to the Promise / A + rule
.then(log);
queue1.unshift(testfn,[0]) //add job (LIFO)
.then(log);
queue1.addLikeArray([3,4],testfn,{'workResolve':log}) //Add multiple jobs with Array, Work done will execute 'workResolve'
.then(log)
queue1.addLikeProps({'a':5,'b':6,'c':7},testfn,{'workResolve':log}) //Add multiple jobs with Map,
.then(log)
//queue1.start(); //queue start;
queue1.go(testfn,['go']).then(log)
/*
Equivalent to:
queue1.push(testfn,['go']).then(console.log);
queue1.start();
* In general, it is convenient to use the 'go'
*/
// Output:
/*
0
1
2
3
4
[ 3, 4 ]
5
6
7
{ a: 5, b: 6, c: 7 }
go
*/
如果你是想加多个promise函数拿数组可以用这个API
queue.addArray([
[testfn,[0]],
[testfn,[1]],
[testfn,[2]],
[testfn,[3]]
],true).then(function(arr){
console.log(arr);
})
// [0,1,2,3]
传入Promise
是不行的
你需要传入执行器 then
函数来 schedule 任务
const array = [then,then,then]
async function queue(array){
const result = []
result.push(await new Promise(array.unshift()))
return result
}
// 返回 Promise
const result = queue(array)
https://github.com/jun-lu/pro...
这个库可以帮你解决串行问题,而且可以串行和并行叠加
比如
new PromiseAsync( Promise.resolve(1), Promise.resolve(2))
.flat((n1, n2)=>{
return Promise.resolve(n1 + n2);
})
.subscribe((data)=>{
// data=3...
})
.start()
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答2.3k 阅读✓ 已解决
3 回答2.1k 阅读✓ 已解决
明白你的意思了,你要这么实现的话不能传入 Promise,因为在你创建 Promise 的一刻它就开始 pending 等待 settlement 了。
你应该传入一系列的 executors ,等上一个 Promise resolved 之后再创建新的 Promise。
数组可以放入函数,会自动 new Promise 并执行函数,其它类型则直接 resolve 掉。如果有 reject 返回第一个。
下面例子可以看到,前面异步的时间更长,但依然按顺序执行