【问题标题】:ES6 Promise - Why does throw from catch() and throw from then() not behave the same way?ES6 Promise - 为什么从 catch() 抛出和从 then() 抛出的行为不同?
【发布时间】:2018-02-04 00:32:57
【问题描述】:

我有这段调用 java 后端的 ES6 代码。 java 后端通常返回状态码 200 和 json 有效负载,但有时会返回状态码 500 和 json 有效负载。对于 200,我想反序列化 json 并将生成的对象传递到 promise 链上。对于 500,我想反序列化 json 并将生成的对象 throw 提交到 promise 链上,即让它命中 catch 块。

以下代码几乎可以满足我的要求:

invoke(className, methodName, args) {
    return this.httpClient
        .fetch('/api/' + className + "/" + methodName,
            {
                method: 'POST',
                body: json(args)
            })
        .catch(response => {
            // Function A
            throw response.json();
        })
        .then(response => {
            // Function B
            return response.json();
        });
}

this.invoke("TestService", "testMethod", {a: 1, b: 2})
    .then(response => {
        // Function C
        console.log(response); // prints the actual json object which I expect
    }).catch(response => {
        // Function D
        console.log(response); // prints: [object Promise]
    });
  • 函数 A 被调用 500。很好。
  • 函数 B 被调用 200。很好。
  • response.json() 在 A 和 B 中返回一个反序列化对象的承诺。很好。
  • 函数 A 导致调用函数 D。很好。
  • 函数 B 导致调用函数 C。很好。
  • 函数 C 的参数响应是反序列化的对象。很好。
  • 但是,函数 D 中的参数 response 不是反序列化对象,而是反序列化对象的承诺。

我已经为此工作了一段时间,但我无法向谷歌解释我的问题是什么。

问题:为什么返回一个promise会“解开”下一个函数的promise,而抛出一个promise会将promise本身传递给下一个函数?

有什么方法可以实现我想要的,即让函数 D 像函数 C 一样获取“解包”对象?

【问题讨论】:

  • Eeeck gad。兑现承诺?这样做的真实原因是什么?你抛出一个拒绝原因,而不是未来的异步操作。

标签: promise es6-promise


【解决方案1】:

您在catch 回调中获得承诺的原因是这是规范。

对于thencatch 回调中的返回 值,规则是该promise 必须在外部promise 解析之前解析,并且解析的值应该是由回报的承诺。来自Promises/A+ specs 2.2.7.1

如果onFulfilledonRejected 返回值x,则运行承诺解决过程[[Resolve]](promise2, x)

该规范中的第 3 章进一步解释了这意味着什么。

但是,对于抛出的异常,情况并非如此,如point 2.2.7.2

如果onFulfilledonRejected 抛出异常e,则必须以e 为理由拒绝promise2。

不会尝试将e 识别为承诺,也不会等待其解决。它按原样抛出,这将是你在下一个catch 中得到的。

解决方案

因此解决方案是返回一个promise,但一个promise会抛出已解析的值(不是promise):

return response.json().then(data => { throw data });

【讨论】:

  • 很好的答案,谢谢。该解决方案效果很好:)
猜你喜欢
  • 1970-01-01
  • 2021-09-21
  • 2011-05-26
  • 1970-01-01
  • 2011-01-26
  • 2017-06-29
  • 1970-01-01
  • 2014-09-11
  • 2013-09-09
相关资源
最近更新 更多