简体   繁体   English

在Promise中混淆错误和拒绝

[英]Confuse about error and reject in Promise

All: 所有:

I am pretty new to JS Promise, there is one confuse when it comes to Promise chaining, say I have a promise chaining like: 我对JS Promise很陌生,在Promise链接方面有一个令人困惑的地方,比如说我有一个像以下链接的承诺:

var p = new Promise(function(res, rej){
})
.then(
    function(data){
    }, 
    function(err){
    })
.then(
    function(data){
    }, 
    function(err){
    })
.catch(
    function(err){
    })

What confuse me: 让我困惑的是:

  1. When the function(err) get called and when the catch get called? 当调用函数(错误)和调用catch时?
  2. How to resolve and reject in then ? 如何解决并拒绝then

Thanks 谢谢

The formular for using a Promise is: 使用Promise的公式是:

var p = new Promise(function(resolve, reject) {

  var condition = doSomething();

  if (condition) {
    resolve(data);
  } else {
    reject(err);
  }

});

There is nothing special about .catch , it is just sugar for .then (undefined, func) , but .catch more clearly communicates that it is purely an error handler. .catch没有什么特别的,它只是.catch .then (undefined, func)糖,但是.catch更清楚地传达它纯粹是一个错误处理程序。

If a Promise does not resolve and no rejection callback is provided in it, it skips forward to the next .then in the chain with a rejection callback in it. 如果Promise没有解决并且没有提供拒绝回调,它会跳转到链中的下一个.then ,其中包含拒绝回调。 The rejection callback is the reject(err) . 拒绝回调是reject(err)

For more detailed explanations see: Javascript Promises - There and Back again . 有关更详细的说明,请参阅: Javascript Promises - There and Back


That is: in your example the . 那就是:在你的例子中。 catch only gets called if the preceding rejection callback has an error in it. 如果前面的拒绝回调中有错误,则只会调用catch That is there is an error in the reject(err) function itself - which has nothing to do with the preceding Promise not resolving. 也就是说, reject(err)函数本身存在错误 - 这与前面的Promise无法解决无关。

You can essentially limit yourself to a rejection callback in the .catch at you end of the .then chain. 你基本上可以把自己局限在一个拒绝回调.catch在您结束的.then链。 Any Error in any .then will then fall through to the .catch . 任何Error在任何.then再将始终陷入.catch One subtlety though: any error in the .catch is not caught. 但有一个微妙之处: .catch任何错误都没有被捕获。

The important thing to know is that the .then() method is always chained onto a Promise, and it returns a new Promise whose value and resolved/rejected state is based on what the function given to it returned. 重要的是要知道.then()方法总是链接 Promise上,它返回一个新的 Promise,其值和解析/拒绝状态基于给它返回的函数。

In your example, if the original Promise resolves, then the first function in your first .then() will get called with the resolved value. 在您的示例中,如果原始Promise结算,则第一个.then()中的第一个函数将使用已解析的值进行调用。 If it returns a value then whatever value it returns will then get ultimately passed into the first function in your second .then(). 如果它返回一个值则返回任何值随后会最终传递到第一个功能在你的第二个 。那么()。 The function in catch will never get called. catch中的函数永远不会被调用。

If the Promise rejects, the second function in your first .then() will get called with the rejected value, and whatever value it returns will become a new resolved Promise which passes into the first function of your second then. 如果Promise拒绝,第一个.then()中的第二个函数将被拒绝的值调用,并且它返回的任何将成为一个新的已解析的Promise,它将传递到你的第二个函数中。 Catch is never called here either. Catch也从未被称为。 It's only if the Promise rejects and you keep returning rejected Promises or throwing errors in both your function(err){} functions that you'll get the function(err){} in your catch block called. 只有当Promise拒绝并且你继续在你的function(err){}函数返回被拒绝的Promises或抛出错误时 ,你将在你的catch块中调用function(err){}

To resolve in your function(data){} functions, all you need to do is return a value (or return a Promise/thenable that later resolves). 要解决function(data){}函数,您需要做的就是返回一个值(或者返回一个稍后解析的Promise / thenable)。 To reject, you would need to either throw an error, actually cause an error, return a new Promise that eventually rejects, or explicitly return Promise.reject(::some value::) . 要拒绝,您需要抛出错误,实际导致错误,返回最终拒绝的新Promise,或显式返回Promise.reject(::some value::)

To resolve in your function(err){} blocks, all you need to do is return a new value. 要解决function(err){}块,您需要做的就是返回一个新值。 You could also return a Promise, in which case that Promise is what will be returned (eventually resolving or rejecting). 你也可以返回一个Promise,在这种情况下,Promise将被返回(最终解析或拒绝)。

In general, it's not wise to define both the resolved and rejected path in the same .then() though: PROMISE.then(fn).catch(fn) is a much safer/clearer practice, because then any errors in the first .then() will be caught by catch. 一般来说,在同一个PROMISE.then(fn).catch(fn)定义已解析和被拒绝的路径是PROMISE.then(fn).catch(fn)PROMISE.then(fn).catch(fn)是一种更安全/更清晰的做法,因为那时第一个中的任何错误。然后()将被catch抓住。 If you do PROMISE.then(fn, fn) instead though, if an error happens in the first function it would NOT get caught by the second: some later chained on method would have to catch it. 相反,如果你做了PROMISE.then(fn, fn) ,如果在第一个函数中发生错误,它就不会被第二个函数捕获:一些后来链接的方法必须捕获它。

  1. Note the example executor function in 请注意示例执行程序函数

    var p = new Promise(function(res, rej){});

    is incomplete. 不完整。 An actual executor function supplied to the Promise constructor must call its first argument ( res ) to resolve the constructed promise, or its second argument ( rej ) to reject the promise. 提供给Promise构造函数的实际执行程序函数必须调用其第一个参数( res )来解析构造的promise,或者调用其第二个参数( rej )来拒绝promise。 These calls are normally made asynchronously but don't have to be in ES6. 这些调用通常是异步进行的,但不必在ES6中。

  2. When a promise is resolved with a Promise object (or any object with a .then property which is a function) nothing happens until the promise object supplied in resolution itself becomes fulfilled or rejected . 当使用Promise对象(或具有.then属性的任何对象是函数)解析promise时,在解析本身提供的promise对象变为满足拒绝之前,不会发生任何事情。 Fulfilled values are passed to .then onFulfilled handlers, rejected values are passed to .then onRejected handlers/listeners/callbacks (depending on your terminology). 达到的值传递给.then onFulfilled处理,拒绝值传递到.then onRejected处理器/监听器/回调(取决于您的术语)。

  3. But when a promise is resolved with a non promise (like) object, listeners supplied as the first parameter to .then are called with the resolution value. 但是当使用非promise(如)对象解析promise时.then将使用分辨率值调用作为.then的第一个参数提供的侦听器。

  4. When a promise is rejected with any value, listeners supplied as the second parameter to .then , or first parameter to .catch , are called with the rejected value. 当一个承诺与任何值拒绝,听众提供作为第二个参数来.then ,或者第一参数.catch ,被称为与被拒绝的值。

  5. .catch is a euphemism for calling .then with the supplied argument as second parameter and omitting the first parameter, as in .catch是调用.catch的委婉说法.then使用提供的参数作为第二个参数并省略第一个参数,如

    Promise.prototype.catch = function( listener) { return this.then(null, listener);};

  6. The behavior of .then registered onFulfill and onReject functions is the same. 的行为.then注册onFulfillonReject功能是一样的。 To reject a chained promise throw an error. 拒绝链式承诺会引发错误。 To fulfill a chained promise return a non promise value. 履行链式承诺会返回非承诺值。 To hold up a chained promise return a promise (or promise like) object. 持有链式承诺会返回一个承诺(或承诺)对象。


  7. (Update) When a parameter supplied to .then( onFulfill, onReject) is missing or not a function object, processing is equivalent to supplying a dummy function from: (更新)当提供给.then( onFulfill, onReject)的参数缺失或不是函数对象时,处理相当于从以下位置提供虚函数:

     function onFulfill( data) { return data;} function onReject( err) { throw err;} 

    This is the usual case when calling then or catch with a single argument. 这是调用thencatch单个参数时的常见情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM