【问题标题】:Why doesn't my Deferred run the error method?为什么我的 Deferred 不运行错误方法?
【发布时间】:2015-08-08 04:49:12
【问题描述】:

我创建了这个简单的代码来模拟resolverejecterror

function $http(){
  var core = {
    factory : function (action) {
      var promise = new Promise( function (resolve, reject) {

        if (action==='resolve')  resolve({r:'Resolved'});
        if (action==='error')    throw Error("error");
        if (action==='reject')   reject({r:'Reject'});
      });
      return promise;

  } 
  };
  return {
    'simulate' : function(a) {
      return core.factory(a);
    }
  };
}

var callback = {
  success : function(data){
     console.log(1, 'success', data.r);
  },
  error : function(data){
     console.log(2, 'error',data.r);
  },
   reject : function(data){
     console.log(3, 'reject', data.r);
  }
};

现在让我们调用它们:

$http().simulate('resolve')
       .then(callback.success,callback.reject)
       .catch(callback.error); //"success" "Reolved"

$http().simulate('reject')
       .then(callback.success,callback.reject)
       .catch(callback.error); //"reject" "Reject"

$http().simulate('error')
       .then(callback.success,callback.reject)
       .catch(callback.error);//"reject" undefined

如您所见,reject/resolve 都有效。

问题:

为什么没有:

 error : function(data){
     console.log(2, 'error',data.r);
  }

函数运行,当我模拟error 时?

Full Jsbin

【问题讨论】:

  • 这是因为你在做data.r 但是当你抛出错误时它不存在这就是为什么你会因为data.r 不存在而变得未定义,至于它为什么调用reject而不是我不知道的错误。而是尝试data.message 而不是data.r 错误之一?
  • 我没有问 undefined,我问的是错误 func :-)
  • 好问题。 then(success,reject)then(success).catch(reject) 相同,所以我猜如果您向 then 提供 reject,它不会执行您的 catch
  • @RGraham 不,不是。
  • 是的,这就是我的意思 - 在某些情况下你会得到不同的行为 - 即在 .then(success).catch(fail) 处理失败处理程序中的成功处理程序中的错误,.then(success, fail) 不会。

标签: javascript promise ecmascript-6


【解决方案1】:

这是因为您的 callback.reject 方法本身正在处理抛出的错误。如果你想让你的callback.error 被调用,那么你需要将callback.reject 方法修改为throw 错误本身或者让它return Promise.reject(data)

【讨论】:

  • 但是我如何在 callback.reject 中将 REJECTERROR 区分开来。 (结果中没有任何字符串搜索)
【解决方案2】:

为什么没有

error : function(data){
    console.log(2, 'error',data.r);
}

函数运行,当我模拟error?

根据 ECMA Script 6 Promise 规范,当您使用 Promise 构造函数创建 Promise 时,创建的 Promise 对象将有两个内部插槽,[[PromiseFulfillReactions]][[PromiseRejectReactions]],它们实际上是列表,它们将容纳所有分别对应相应的完成和拒绝处理程序。

当您将then 处理程序附加到promise 对象时,履行处理程序将被添加到[[PromiseFulfillReactions]] 列表中,而拒绝处理程序将被添加到[[PromiseRejectReactions]] 列表中。当 promise 完成时,[[PromiseFulfillReactions]] 中的所有处理程序都会被调用,同样,当状态从pending 变为rejected 时,所有拒绝处理程序都会被调用。

在这两种情况下,

$http().simulate('reject')
       .then(callback.success, callback.reject)
       .catch(callback.error);   //"reject" "Reject"

$http().simulate('error')
       .then(callback.success, callback.reject)
       .catch(callback.error);  //"reject" undefined

$http().simulate('reject')$http().simulate('error') 创建新的承诺,当你附加 then 处理程序时,callback.successcallback.reject 被添加到各自的反应列表中。在这两种情况下,抛出 Error 并拒绝将被视为仅拒绝承诺。因为在 [[PromiseRejectReactions]] 中只有一个处理程序用于执行这两种情况。这就是为什么在这两种情况下都只调用了callback.reject


如果你已经定义了最后一种情况,像这样

$http().simulate('error')
       .then(callback.success)
       .catch(callback.error);

现在,then 处理程序没有 onRejected 处理程序。但这里要注意的重点是,所有 then 处理程序都将创建新的 Promise 并返回它们。因此,由于当前的then 没有拒绝处理程序,它将创建一个被拒绝的承诺并返回它。而.catch(callback.error) 只是.then(undefined, callback.error) 的语法糖。被拒绝的 Promise 的拒绝反应列表将获得 callback.error 函数,并且该函数将在 Promise 被拒绝时被调用。

【讨论】:

    猜你喜欢
    • 2015-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-05
    • 1970-01-01
    • 2015-01-30
    相关资源
    最近更新 更多