the*_*eye 26 javascript node.js promise q
在我的代码中,基于特定条件,我想跳到done函数,而不管所有then函数.
该问题的原始版本在编辑中.以下是我正在处理的实际问题.抱歉给你带来不便
实际问题:
我正在读取文件并进行处理.如果文件的内容符合某些条件,我必须对文件系统进行一系列操作(比如读写几个文件),然后执行done函数.如果条件失败,我必须跳过所有系列操作,我必须done直接执行该功能.
我result在所有then函数中返回一个对象(比如说),然后then我更新result并返回它.所以,当所有的then事情都完成后,done就会有所累积result.最后,done将处理result并打印它.
因此,如果最初不满足条件,done则只需打印result(这将是空的).
Q()
.then(readFile)
.then(function (contents) {
var processResult = process the contents;
if (processResult) {
return {};
} else {
// How can I skip to `done` from here
}
})
.then(function (results) {
// do some more processing and update results
return results;
})
... // Few more then functions similar to the one above
...
.fail(function (exception) {
console.error(exception.stack);
})
.done(function (results) {
// do some more processing and update results
console.log(results);
});
Run Code Online (Sandbox Code Playgroud)
pok*_*oke 24
这取决于要跳过的条件是什么,你正在做什么样的操作,以及当条件失败时整个事情是多么"有用".您可以在此处使用智能拒绝来传达消息.否则,我认为处理这个问题的正确方法实际上是一组嵌套的promise调用.
这也符合promises背后的核心思想,即将同步控制结构带回异步代码执行.通常,在使用promises时,首先应考虑如何使用同步代码完成任务.如果你考虑一下你的情况,它可能会像这样:
var contents = readFromFile();
var results = initialOperation(contents);
if (fancyCondition(results)) {
results = doSomething(results);
results = doMore(results);
}
processAndPrint(results);
Run Code Online (Sandbox Code Playgroud)
所以你会在同步代码中有一个真正的分支.因此,使用promises在异步代码中避免使用它是没有意义的.如果你可以跳过一些东西,那你基本上就是使用带有gotos的跳转.但相反,你分开并分开做其他事情.
因此,回到promises和异步代码,拥有另一组链接操作的实际分支是完全正确的,并且实际上是承诺背后的意图.所以上面的代码看起来像这样:
readFromFile(fileName)
.then(initialOperation)
.then(function (results) {
if (fancyCondition(results) {
return doSomething(results)
.then(doMore);
}
return results;
})
.catch(errorHandler)
.then(processResults)
.then(outputResults); // Or `done` in Q
Run Code Online (Sandbox Code Playgroud)
另请注意,当您开始使用自己返回promises的函数时,promise管道会自动看起来更清晰,而不是从内联创建它们then.
但后来我们正在嵌套可靠的函数.这是我们想要首先使用promises避免的.
不,这确实是正确的方法.对于分支,您将始终需要额外的嵌套级别.如果缩进变得太大,您仍然可以应用调用子过程的旧技巧(它也用于取消回调函数).
其他解决方案非常难看.跳过then链中的几个处理程序,没有更深的嵌套,可以通过抛出异常并拒绝承诺来完成; 这可能最终被抓住了.它可能适用于几种情况,但我不认为这是一个好主意.
我能想到的另一种方法是将条件结果包装在另一个数据结构中,该数据结构可以通过thens 链传递.这就像Maybe在Haskell或OptionScala中一样,你会map在处理程序中覆盖它们.但是,这还需要额外的嵌套级别,通过链显式传播任何内容的效率会降低,并且链中的返回promise将会出现问题.