我试图创建一个阻塞控制流,但已经达到了死胡同。其思想是,请求传入并通过许多处理程序函数流动。每个函数都会做一些事情,并决定请求现在是否得到满足。如果是,则停止处理,如果不是,则调用下一个处理程序。每个处理程序可能或不可能异步执行某些操作(比如获取/写入数据)。如果是这样的话,那么下面的处理程序取决于启动前的数据。
到目前为止,我有两种想法,它们都不完全符合这些要求: 1)所有处理程序都是函数,它们被推入数组并使用some
进行迭代。如果处理程序希望停止控制流,则只需返回true
。使用这种方法,我不能让任何一个处理程序调用异步函数。
2)所有处理程序都是有链锁的承诺。这似乎是一个更好的主意,但我不知道如何最好地处理停止控制流。我有两个想法:-保留一个变量,一旦处理程序决定中断流,这个变量就被设置为true
。在每个处理程序中检查此值,并在需要时立即解析。这意味着有很多重复的代码。-拒绝承诺,如果它不希望继续正常流动,并继续在catch
。然而,使用错误作为控制流的一种手段的想法让我感到痛苦--这也意味着我必须处理由于实际错误而调用捕获的情况。
我的体感告诉我一定有别的办法,但我想不出来。
发布于 2016-06-09 18:59:31
不要把承诺的操纵者拴在一起,把它们嵌套起来。您可以从一个函数数组中以编程方式完成此操作:
var handlers = […]; // functions that can return promises
var run = handlers.reduceRight(function(next, handler) {
return function() {
return Promise.resolve(someArg).then(handler).then(function(result) {
if (result) // true, whatever
return result;
else
return next();
});
};
}, function end() {
return Promise.reject(new Error("no handler matched"));
});
run().then(function(result) {
// the result from the first handler that returned anything
}, function(err) {
// some handler threw an exception, or there was no handler
});
发布于 2016-06-09 20:35:07
您可以使用ES6生成器根据需要生成承诺。每次承诺解决时,它都可以检查停止值,如果false (即继续到下一个处理程序)请求迭代器中的下一个。
function* promiseHandlers() {
const handlers = [
promiseHandler1,
promiseHandler2,
promiseHandler3,
promiseHandler4,
promiseHandler5
];
for (const handler of handlers) {
yield handler();
}
}
function run(iter) {
const i = iter.next();
if (i.done) {
return Promise.reject(new Error("end of iterator reached"));
}
return Promise.resolve(i.value).then(result => result || run(iter));
}
run(promiseHandlers());
但这并不是真正的链子。相反,它将按照顺序执行每个promiseHandler,但这些结果不会传递给下一个promiseHandler。我认为这对于OP所希望的是正确的,特别是因为一个真实的结果结束了迭代(即中断)。
https://stackoverflow.com/questions/37732741
复制相似问题