我们需要按顺序运行一些javascript函数。这些函数存储在一个数组中:
m = [
function(){...},
function(){...},
...
function(){...}
]
从第一个函数开始,使用初始参数运行它,并检查它是否返回Promise。如果没有,请将其包装在promise调用中并返回promise。
当promise被解决时,我们希望它运行下一个函数,参数是前一个函数的结果。
如果其中一个函数返回false
,则停止执行并返回false
我是函数式编程的新手,我相信我在这里错过了一个核心概念。
TIA,
答案 0 :(得分:4)
考虑
let seq = ps => ps.reduce((p, f) => p.then(x => x && f(x)), Promise.resolve(true));
a = [
x => 'a',
x => x + 'b',
x => x + 'c',
];
seq(a).then(console.log.bind(console));
b = [
x => 'a',
x => false,
x => x + 'c',
];
seq(b).then(console.log.bind(console));

答案 1 :(得分:1)
有点粗糙,但以下内容应该有效:
/**
* Process array of functions and return a promise which will
* contain the result of the last function, or false.
*
* @param {Array} funcs - Array of functions to be called in sequence
* @return {bool | mixed} - False, or return of last function
*/
const processFuncs = await (funcs) => {
if( ! Array.isArray(funcs))
return Promise.resolve(false);
try{
return await funcs.reduce(
async (res, f) => await res && f(...res);
, true);
}
catch(err){
return Promise.reject(err);
}
}
这假定您的构建和/或目标支持ES6 +功能。
要使用OPs原始变量,只需调用:
const result = processFuncs(m); // Will be a promise which resolves to the return of the last function, or false
答案 2 :(得分:0)
我刚刚创建了fiddle作为预期行为的示例:它按顺序运行多个promise并在其中一个promises返回false时停止该序列(此外我编码返回一个带有当没有承诺返回错误时,承诺的结果。) 如果函数没有返回一个promise,而是另一个函数,后者将被包含在一个promise中,该promise将用函数的结果解析。
这是你的阵列:
let yourFunctionArray = [
function() {
return function() {
return "hello"; //The promise resolution.
};
}
];
这是承诺所有承诺的承诺。
let work = new Promise(async function(resolve, reject) {
let results = [];
let _break = false;
for (let array = yourFunctionArray, i = 0, l = array.length, f = array[i]; i < l; i++, f = array[i]) {
if (_break)
break;
let promise = f();
if (!promise) {
reject();
return;
}
if (!promise.then)
promise = new Promise(function(resolve, reject) {
resolve(promise());
});
await promise.then(async function(result) {
if (result === false) {
resolve(false);
_break = true;
} else
results.push(result);
});
}
resolve(results);
});
现在你可以运行这个承诺:
work.then(function(response) {
alert("completed with " + response);
});
答案 3 :(得分:0)
这主要是对来自@supports at-rule的excellent answer的一个小改动。
它允许您将多个参数传递给初始函数。它也会跳过他的假测试,我不太明白。处理多个参数使得它比底层let seq = ps => init => ps.reduce((p, f) => p.then(f), Promise.resolve(init))
更复杂,因此除非有多个参数是真正可能的,否则它不值得使用。
let seq = ps => (...init) => ps.slice(1).reduce(
(p, f) => p.then(f),
Promise.resolve(ps.length ? ps[0].apply(null, init) : init)
)
// Note that the first function takes multiple arguments
seq([
(x, y) => x + y,
x => x + 1,
x => x * 2
])(3, 2).then(console.log)
// Functions can return Promises or plain values
// A Promise rejection is carried through
const foo = seq([
x => Promise.resolve(x * 2),
x => Promise.reject('oops'),
x => x + 1
])
foo(5).then(console.info, console.error)
&#13;