何时拒绝/解决承诺

我在想什么时候我需要拒绝承诺。 我发现了几个关于这个话题的问题,但是找不到合适的答案。 我应该什么时候拒绝承诺?

这篇文章http://howtonode.org/6666a4b74d7434144cff717c828be2c3953d46e7/promises说:

  • 解决:一个成功的Promise被“解决”,它调用正在等待的成功侦听器,并记住为未来成功侦听器parsing的值。 分辨率与返回的值相关。
  • 拒绝:遇到错误情况时,Promise被拒绝,它调用正在等待的错误侦听器,并记住被连接的未来错误侦听器拒绝的值。 拒绝与抛出的exception相关。

这是原则指引吗? 那只有在发生exception时才拒绝承诺?

但是在遇到类似的function的情况下

findUserByEmail() 

我会希望该函数返回一个用户,以便我可以继续链而不validation结果

 findUserByEmail() .then(sendWelcomeBackEmail) .then(doSomeNiceStuff) .then(etc..) 

什么是最好的/常见的做法?

一般来说,你可以认为拒绝是类似于同步throw并认为是类似于同步return 。 您应该以某种方式拒绝function不成功。 这可能是超时,networking错误,input错误等。

拒绝承诺,就像抛出一个exception一样,对控制stream程很有用。 它不一定代表一个真正意想不到的错误; 它可以代表你完全预期和处理的一个问题:

 function getProfile(email) { return getProfileOverNetwork(email) .then(null, function (err) { //something went wrong getting the profile if (err.code === 'NonExistantUser') { return defaultUser; } else if (profileCached(email)) { return getProfileFromCache(email);//fall back to cached profile } else { throw err;//sometimes we don't have a nice way of handling it } }) } 

拒绝让我们跳过正常的成功行为,直到我们得到一个知道如何处理它的方法。 作为另一个例子,我们可能有一些function深深地嵌套在应用程序堆栈的底部,这被拒绝。 这可能不会被处理,直到堆栈的顶部,我们可以logging它。 重点在于拒绝在栈中移动,就像asynchronous代码中的exception一样。

一般情况下,如果你正在努力编写一些asynchronous代码,你应该考虑“如果这是同步的,我会写什么”。 通常是一个相当简单的转换,从承诺的等价。 A nice example of where rejected promises might be used is in an方法:

 function exists(filePath) { return stat(filePath) //where stat gets last updated time etc. of the file .then(function () { return true; }, function () { return false; }) } 

请注意,在这种情况下,拒绝是完全预期的,只是意味着文件不存在。 也请注意它是如何与同步function并行的:

 function existsSync(filePath) { try { statSync(filePath); return true; } catch (ex) { return false; } } 

你的例子

回到你的例子:

如果没有用户被发现,我通常会select拒绝findUserByEmail的承诺。 这是你有时会完全期望的事情,但是这是规范的例外情况,应该像所有其他错误一样处理。 同样,如果我正在写一个同步函数,我会让它throw一个exception。

有时,只是返回null可能是有用的,但是这取决于您的应用程序逻辑,可能不是最好的方法。

我知道你从哪里来。 Q和Q文档很容易让你相信延迟/承诺拒绝是关于exception处理的。

事实并非如此。

无论您的申请需要什么原因,延期都可以被拒绝。

延迟/承诺都是关于处理来自asynchronous进程的响应,每个asynchronous进程都可能导致各种结果 – 其中一些是“成功”,一些是“不成功”。 无论是出于何种原因,无论结果是名义上成功还是失败,无论是以javascript还是asynchronous过程,您都可以select拒绝延迟 – 无论是否已经抛出exception。

您也可以select在asynchronous进程上实现超时,在这种情况下,您可以select拒绝没有收到响应(成功或失败)的延迟。 事实上,对于超时,这是你通常会select做的事情。