所有
我对JS Promise很陌生,当谈到Promise链接时,有一个混淆,说我有一个链接的承诺:
var p = new Promise(function(res, rej){
})
.then(
function(data){
},
function(err){
})
.then(
function(data){
},
function(err){
})
.catch(
function(err){
})
令我困惑的是:
then
中解决和拒绝?由于
答案 0 :(得分:13)
使用Promise的公式是:
var p = new Promise(function(resolve, reject) {
var condition = doSomething();
if (condition) {
resolve(data);
} else {
reject(err);
}
});
.catch
没有什么特别之处,它只是.then (undefined, func)
的糖,但.catch
更清楚地表明它纯粹是一个错误处理程序。
如果Promise
未解决且未在其中提供拒绝回调,则会跳转到链中的下一个.then
,其中包含拒绝回调。拒绝回调是reject(err)
。
有关详细说明,请参阅:Javascript Promises - There and Back again。
即:在您的示例中,如果前面的拒绝回调中包含错误,则仅调用。catch
。那就是reject(err)
函数本身存在错误 - 这与前面的Promise
无法解析无关。
您实际上可以将自己限制在.catch
链末尾的.then
拒绝回调。任何Error
中的任何.then
都将落入.catch
。但有一个微妙之处:.catch
中的任何错误都没有被捕获。
答案 1 :(得分:6)
重要的是要知道.then()方法始终链接到一个Promise上,它返回一个 new Promise,其值和已解决/拒绝状态是基于给它的函数返回的。
在您的示例中,如果原始Promise结算,则第一个.then()中的第一个函数将使用已解析的值进行调用。如果它返回一个值,那么 it 返回的任何值将最终传递到 second .then()中的第一个函数。 catch中的函数永远不会被调用。
如果Promise拒绝,你的第一个.then()中的第二个函数将被拒绝的值调用,并且它返回的值将成为一个新的已解析的Promise,它将进入第一个函数然后你的第二个。 Catch也从未被称为。只有当Promise拒绝并且你继续拒绝承诺或在你的function(err){}
函数中抛出错误时,你将在你的catch块中获得function(err){}
。
要在function(data){}
函数中解决,您需要做的就是返回一个值(或返回一个稍后解析的Promise / thenable)。
要拒绝,您需要抛出错误,实际上导致错误,返回最终拒绝的新Promise,或显式返回Promise.reject(::some value::)
。
要在function(err){}
块中解析,您需要做的就是返回一个新值。你也可以返回一个Promise,在这种情况下,Promise将被返回(最终解析或拒绝)。
一般来说,在同一个.then()中定义已解析和被拒绝的路径并不明智。PROMISE.then(fn).catch(fn)
是一个更安全/更清晰的做法,因为那时第一个.then()中的任何错误将被抓住抓住。相反,如果你做了PROMISE.then(fn, fn)
,如果在第一个函数中发生错误,它就不会被第二个函数捕获:一些后来链接在方法上的东西必须抓住它。
答案 2 :(得分:3)
请注意
中的示例执行程序函数 var p = new Promise(function(res, rej){});
不完整。提供给Promise构造函数的实际执行函数必须调用其第一个参数(res
)来解析构造的promise,或者它的第二个参数(rej
)来拒绝promise。这些通话通常是异步进行的,但不一定要在ES6中。
使用Promise对象(或任何具有.then
属性的对象解析promise)时,在分辨率本身提供的promise对象变为 或拒绝。已完成的值会传递给.then
onFulfilled
个处理程序,被拒绝的值会传递给.then
onRejected
个处理程序/侦听器/回调(取决于您的术语)。
但是当使用非promise(如)对象解析promise时,将使用分辨率值调用作为.then
的第一个参数提供的侦听器。
当使用任何值拒绝承诺时,将使用被拒绝的值调用作为.then
的第二个参数或.catch
的第一个参数提供的侦听器。
.catch
是使用提供的参数作为第二个参数调用.then
并省略第一个参数的委婉说法,如
Promise.prototype.catch = function( listener) { return this.then(null, listener);};
.then
注册onFulfill
和onReject
功能的行为相同。拒绝链式承诺会引发错误。履行链式承诺会返回非承诺值。持有链式承诺会返回一个承诺(或承诺)对象。
(更新)当提供给.then( onFulfill, onReject)
的参数缺失或不是函数对象时,处理等同于从以下位置提供虚拟函数:
function onFulfill( data) { return data;}
function onReject( err) { throw err;}
通过一个参数调用then
或catch
时,这是常见的情况。