【问题标题】:Promise - wrapping error during deferred.rejectPromise - deferred.reject 期间的包装错误
【发布时间】:2013-11-15 07:54:01
【问题描述】:

我正在尝试使用q.js 创建一个延迟包装器,这样我就可以将错误(字符串)包装在自定义错误类中,然后再由then() 或fail() 中的承诺传回。这就是我目前正在做的事情:

var getDeferred = function() {

    var deferred = q.defer();

    var reject = deferred.reject;
    deferred.reject = function(error) {

        if (!(error instanceof MyErrorClass))
            error = new MyErrorClass(error)

        return reject.apply(deferred, arguments);
    }

    return deferred;
}

所以这个想法是用户会做类似的事情

var deferred = getDeferred();

deferred.promise.fail(function(err) {
    // err should now be instance of MyErrorClass and NOT a string
})

deferred.reject('A string error')

并期望在fail() 处理程序中获得MyErrorClass,而不是传递给deferred.reject 的字符串。

上面的代码有效,但并不理想——我知道我不应该给 deferred.reject 打猴子补丁。但是有没有更好的方法来做到这一点?

【问题讨论】:

  • 好吧,一般来说,您根本不应该使用延迟。编写手动代码来承诺回调 API 是对代码的巨大浪费。不幸的是 Q.nbind 不会自动包装字符串错误,但您始终可以编写自己的实现。
  • @Esailija -- 我只是想感谢你的评论,它澄清了我对 Promise 的理解。最初我认为创建 deferred 是创建新 promise 的规范方式。我一直在玩 q.js,现在事情变得简单多了。

标签: javascript node.js promise q


【解决方案1】:

这样更漂亮/更面向承诺:

var getDeferred = function() {

    var deferred = q.defer();

    deferred.promise = deferred.promise.then(null, function(error) {
        if (!(error instanceof MyErrorClass))
            error = new MyErrorClass(error)

        throw error
    }

    return deferred;
}

这样你只需附加一个错误处理程序,它将改变任何非MyErrorClass 错误。总的来说,这似乎是一个奇怪的用例......

【讨论】:

  • 漂亮,谢谢。我知道这是一个奇怪的用例,它是说服人们转向现有代码库上的承诺的案例之一,同时支持当前回调汤所做的一些相同的事情。
【解决方案2】:

使用then 简单地映射失败案例:

actualPromise.then(null, function(error) {
    if (!(error instanceof MyErrorClass))
        error = new MyErrorClass(error)
    throw error;
})
.fail(function(err) {
    // err is now an instance of MyErrorClass and NOT a string
});

如果您需要包装器功能,请使用接受 actualPromise 并调用带有上述代码的 then 的函数。

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 2020-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多