我有这个ES6代码调用java后端 . 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]
});
-
函数A被调用500.好 .
-
函数B被调用为200.好 .
-
response.json()返回A和B中反序列化对象的承诺 . 好 .
-
函数A导致调用函数D.好 .
-
函数B导致调用函数C.好 .
-
函数C的参数,响应是反序列化的对象 . 好 .
-
But ,函数D中的参数,响应不是反序列化的对象,而是反序列化对象的承诺 .
我已经在这方面工作了一段时间,但我很难解释谷歌我的问题是什么 .
Question: 为什么返回一个承诺'unwrap'下一个函数的承诺,但抛出一个承诺将承诺本身传递给下一个函数?
有没有什么方法可以实现我想要的,这是函数D得到'解包'对象就像函数C一样?
1 回答
你在
catch
回调中得到承诺的原因是这是规范 .对于
then
或catch
回调中的返回值,规则是该promise必须在外部promise解析之前解析,并且已解析的值应该是返回的promise承诺的值 . 来自Promises/A+ specs 2.2.7.1:该规范中的第3章进一步解释了这意味着什么 .
但是,对于抛出异常,情况并非如此,如point 2.2.7.2中所示:
没有试图承认
e
是承诺,也不是等待其解决 . 它按原样抛出,这将是你在下一个catch
得到的 .解决方案
因此,解决方案是返回一个promise,但是一个将抛出已解析值(而不是promise)的promise: