运行 功能 return 在承诺完成后连续承诺
Run functions that return promises in series after promise is done
我有一组函数需要执行。
这些功能都是 return 一个承诺。
我想运行串联所有的功能,但是只有完成上一个功能的promise才能启动下一个功能
我认为使用 async 或 bluebird 库会很容易,但我找不到简单的解决方案。
这是我做的(未经测试),但我一直在寻找标准库解决方案,因为它可能已经存在?
function runFuncs(funcs) {
function funcRunner(funcs, resolve, reject, pos=0) {
funcs[pos]().then(function() {
pos++;
if (pos < length(funcs)) {
funcRunner(funcs, pos);
} else {
resolve();
}
}).catch(function(err) {
reject(err);
});
}
return new Promise(function(resolve, reject) {
funcRunner(funcs, resolve, reject);
});
}
如果每个函数 return 本身就是一个 promise,您可以将它们链接在一起。这样的事情应该有效:
function runFuncs(funcs) {
return funcs.reduce(function (p, funcToRun) {
return p.then(function () {
return funcToRun();
});
}, Promise.resolve(null));
}
基本上,您只需将承诺链接在一起即可。根据链的性质,如果您 return 来自 then
处理程序的承诺,它就会成为结果承诺。所以 reduce 调用遍历数组中的每个 promise,对其执行 then
以处理数组中的下一个。
不使用额外的库,只使用普通的旧 JS 代码,我能够想出一个简单的解决方案。
'use strict';
// Create an array of functions that return a promise
const promises = [];
let i = 0;
while (i++ < 10) {
const v = i;
promises.push(() => {
return new Promise( (resolve, reject) => {
setTimeout(() => {
resolve(v);
}, Math.floor(Math.random() * 1000));
});
});
}
function nextPromise(idx) {
if (idx >= promises.length) return;
promises[idx]().then((v) => {
console.log("Resolved", v);
nextPromise(++idx);
});
}
nextPromise(0);
在这个例子中,我创建了一个包含 10 个函数的数组,每个函数 returns 一个在随机毫秒数后解析单调递增数字的承诺。
为了按顺序执行它们,我只使用了一些递归。这是一种看起来有点丑陋的 hackkey 代码,但它确实有效。
我知道你已经标记了一个答案,但我还不能发表评论,不得不问:你的例子似乎没有将结果从一个函数传递到另一个函数,你真的需要它们吗运行 串联?
如果系列是一项硬性要求,Bluebird 的 .mapSeries()
method will do exactly what you're looking for, and the code is incredibly neat. Otherwise you can swap in .map()
并利用并发来并行完成工作。
Promise.mapSeries(fnArray, (fn) =>
{
return fn(...);
})
.then((results) =>
{
// do something with the results.
});
或与.map()
并行:
Promise.map(fnArray, (fn) =>
{
return fn(...);
},
{ concurrency: 5 })
.then((results) =>
{
// do something with the results.
});
如果 "funcs" 是承诺数组,您可以使用 Promise.all() - Promise docs
import {Promise} from 'es6-promise';
const runFuncs = funcs => {
return Promise.all(funcs);
};
export default runFuncs;
我有一组函数需要执行。 这些功能都是 return 一个承诺。
我想运行串联所有的功能,但是只有完成上一个功能的promise才能启动下一个功能
我认为使用 async 或 bluebird 库会很容易,但我找不到简单的解决方案。
这是我做的(未经测试),但我一直在寻找标准库解决方案,因为它可能已经存在?
function runFuncs(funcs) {
function funcRunner(funcs, resolve, reject, pos=0) {
funcs[pos]().then(function() {
pos++;
if (pos < length(funcs)) {
funcRunner(funcs, pos);
} else {
resolve();
}
}).catch(function(err) {
reject(err);
});
}
return new Promise(function(resolve, reject) {
funcRunner(funcs, resolve, reject);
});
}
如果每个函数 return 本身就是一个 promise,您可以将它们链接在一起。这样的事情应该有效:
function runFuncs(funcs) {
return funcs.reduce(function (p, funcToRun) {
return p.then(function () {
return funcToRun();
});
}, Promise.resolve(null));
}
基本上,您只需将承诺链接在一起即可。根据链的性质,如果您 return 来自 then
处理程序的承诺,它就会成为结果承诺。所以 reduce 调用遍历数组中的每个 promise,对其执行 then
以处理数组中的下一个。
不使用额外的库,只使用普通的旧 JS 代码,我能够想出一个简单的解决方案。
'use strict';
// Create an array of functions that return a promise
const promises = [];
let i = 0;
while (i++ < 10) {
const v = i;
promises.push(() => {
return new Promise( (resolve, reject) => {
setTimeout(() => {
resolve(v);
}, Math.floor(Math.random() * 1000));
});
});
}
function nextPromise(idx) {
if (idx >= promises.length) return;
promises[idx]().then((v) => {
console.log("Resolved", v);
nextPromise(++idx);
});
}
nextPromise(0);
在这个例子中,我创建了一个包含 10 个函数的数组,每个函数 returns 一个在随机毫秒数后解析单调递增数字的承诺。
为了按顺序执行它们,我只使用了一些递归。这是一种看起来有点丑陋的 hackkey 代码,但它确实有效。
我知道你已经标记了一个答案,但我还不能发表评论,不得不问:你的例子似乎没有将结果从一个函数传递到另一个函数,你真的需要它们吗运行 串联?
如果系列是一项硬性要求,Bluebird 的 .mapSeries()
method will do exactly what you're looking for, and the code is incredibly neat. Otherwise you can swap in .map()
并利用并发来并行完成工作。
Promise.mapSeries(fnArray, (fn) =>
{
return fn(...);
})
.then((results) =>
{
// do something with the results.
});
或与.map()
并行:
Promise.map(fnArray, (fn) =>
{
return fn(...);
},
{ concurrency: 5 })
.then((results) =>
{
// do something with the results.
});
如果 "funcs" 是承诺数组,您可以使用 Promise.all() - Promise docs
import {Promise} from 'es6-promise';
const runFuncs = funcs => {
return Promise.all(funcs);
};
export default runFuncs;