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