我有一段调用java后端的ES6代码。 java后端通常返回状态代码200和json有效负载,但有时返回状态代码500和json有效负载。对于200,我想反序列化json并将结果对象传递给promise链。对于500,我想反序列化json并将抛出结果对象带到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]
});
我已经在这方面工作了一段时间,但我在解释谷歌问题时遇到了问题。
问题:为什么要回复承诺'展开'下一个函数的承诺,但抛出一个承诺将承诺本身传递给下一个函数?
有什么方法可以达到我想要的效果,这是因为功能D可以让你解开'对象就像函数C?
答案 0 :(得分:3)
你在catch
回调中得到承诺的原因是这是规范。
对于<{1}}或then
回调中返回的值,规则是该promise必须在外部promise解析之前解析,并且解析后的值应为返回的承诺承诺的价值。来自Promises/A+ specs 2.2.7.1:
如果
catch
或onFulfilled
返回值onRejected
,请运行承诺解决程序x
。
该规范中的第3章进一步解释了这意味着什么。
但是,抛出异常并非如此,如point 2.2.7.2中所示:
如果
[[Resolve]](promise2, x)
或onFulfilled
引发异常onRejected
,则必须以e
为由拒绝promise2。
不会尝试将e
视为承诺,也不会等待其解决。它按原样抛出,这将是你在下一个e
中得到的结果。
因此,解决方案是返回一个承诺,但承诺会抛出已解决的值(而不是承诺):
catch