[英]Implement blocking control flow in NodeJS
我正在尝试创建一个阻塞控制流程,但已经走到了死胡同。 这个想法是请求进入并流经许多处理函数。 每个功能都会执行某些操作,并决定是否现在满足请求。 如果是,则处理停止,否则,调用下一个处理程序。 每个处理程序可能会也可能不会异步执行某些操作(如获取/写入数据)。 如果是这种情况,那么以下处理程序依赖于启动之前的数据。
到目前为止,我有两个想法,它们都不能满足这些要求:1)所有处理程序都是函数,它们被推入一个数组并迭代some
。 如果处理程序希望停止控制流,则只需返回true
。 使用这种方法,我不能让任何处理程序调用异步函数。
2)所有处理程序都是链接的承诺。 这对我来说似乎是一个更好的主意,但我无法弄清楚如何最好地处理停止控制流程。 我有两个想法: - 一旦处理程序决定中断流程,保留一个设置为true
的变量。 在每个处理程序中检查此值,并在需要时立即解决。 这意味着很多重复的代码。 - 拒绝承诺,如果它不希望继续正常流动,并继续catch
。 然而,使用错误作为控制流程的手段的想法让我很痛苦 - 而且这意味着我必须处理由于实际错误而调用catch的情况。
我的蜘蛛般的感觉告诉我必须有另一种方式,但我无法弄清楚。
您可以根据需要使用ES6生成器生成promise。 每次promise都解析时,它可以检查一个停止值,如果为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,但这些的结果不会传递给下一个。 我认为这对于OP想要的是正确的,因为一个真实的结果结束了迭代(即中断)。
不要链接承诺处理程序,嵌套它们。 您可以通过一系列函数以编程方式执行此操作:
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
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.