Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Promise ES6承诺-为什么catch()和then()的抛出行为不一样?_Promise_Es6 Promise - Fatal编程技术网

Promise ES6承诺-为什么catch()和then()的抛出行为不一样?

Promise ES6承诺-为什么catch()和then()的抛出行为不一样?,promise,es6-promise,Promise,Es6 Promise,我有一段调用java后端的ES6代码。java后端通常返回状态代码200和json负载,但有时返回状态代码500和json负载。对于200,我想反序列化json并将结果对象向上传递到promise链。对于500,我想对json进行反序列化,并将结果对象抛出承诺链,即让它命中catch块 以下代码几乎满足了我的要求: invoke(className, methodName, args) { return this.httpClient .fetch('/api/' + c

我有一段调用java后端的ES6代码。java后端通常返回状态代码200和json负载,但有时返回状态代码500和json负载。对于200,我想反序列化json并将结果对象向上传递到promise链。对于500,我想对json进行反序列化,并将结果对象抛出承诺链,即让它命中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次。好
  • json()返回a和B中的反序列化对象的承诺。很好
  • 函数A导致调用函数D。好
  • 函数B导致调用函数C。好
  • 函数C的参数response是反序列化对象。好
  • 但是,函数D中的参数response不是反序列化对象,而是反序列化对象的承诺
我已经在这方面工作了一段时间,但我很难向谷歌解释我的问题是什么

问题:为什么返回承诺会“打开”下一个函数的承诺,而抛出承诺会将承诺本身传递到下一个函数中


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

catch
回调中获得承诺的原因是,这是通过规范实现的

对于
then
catch
回调中的返回值,规则是该承诺必须在外部承诺解析之前解析,并且解析的值应该是返回的承诺所承诺的值。从:

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

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

但是,对于抛出的异常,情况并非如此,如中所示:

如果
oncompleted
onRejected
引发异常
e
,则必须以
e
为理由拒绝承诺2

未试图将
e
视为承诺或等待其解决。它按原样抛出,这将是您在下一个
捕获中得到的

解决方案 因此,解决方案是返回一个承诺,但该承诺将抛出已解析的值(而不是承诺):


您在
catch
回调中得到承诺的原因是这是通过规范实现的

对于
then
catch
回调中的返回值,规则是该承诺必须在外部承诺解析之前解析,并且解析的值应该是返回的承诺所承诺的值。从:

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

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

但是,对于抛出的异常,情况并非如此,如中所示:

如果
oncompleted
onRejected
引发异常
e
,则必须以
e
为理由拒绝承诺2

未试图将
e
视为承诺或等待其解决。它按原样抛出,这将是您在下一个
捕获中得到的

解决方案 因此,解决方案是返回一个承诺,但该承诺将抛出已解析的值(而不是承诺):


艾克·盖德。放弃承诺?现实世界中这样做的理由是什么?抛出拒绝原因,而不是将来的异步操作。Eeeck gad。放弃承诺?现实世界中这样做的理由是什么?您抛出的是拒绝原因,而不是将来的异步操作。回答得很好,谢谢。答案很好:)回答得很好,谢谢。解决方案非常有效:)
return response.json().then(data => { throw data });