为什么Typescript认为async/await返回承诺中包含的值?
我想将promise链重构为async/await,但Typescript正在抱怨打字。为什么Typescript认为async/await返回承诺中包含的值?
TS2322:类型 'IHttpPromiseCallbackArg < IResp>' 是不能分配给键入 'IResp' ......
我想await
将返回常规值,而不是一个承诺。我错了吗?如果是这样,我如何分配一个键入以便编译所需的代码?
我以为await会返回与.then回调中第一个参数相同的值。我错了吗?
旧代码:
handleSubmit(form) {
const params = this.getParams(form);
this.myAsyncRequest(params)
.then((resp:IResp) => this.processResp(resp))
.catch((e:IServerError) => this.handleError(e));
}
所需的新代码:
async handleSubmit(form) {
const params = this.getParams(form);
try {
const resp:IResp = await this.myAsyncRequest(params); //typing error with "const resp:IResp"
this.processResp(resp);
} catch (e:IServerError) {
this.handleError(e);
}
}
如果我删除myAsyncRequest
返回类型所需的代码仍然打破;我认为Typescript直接从AngularJS库中推断出来。
myAsyncRequest(params:IParams):IHttpPromise<IResp> {
return $http.post('blah', data);
}
如果我从常量RESP声明中删除 “IResp”,processResponse抱怨IHttp < IResp>不等于IResp ...
processResp(resp:IResp) {
//do stuff
}
您的问题“我以为等待会返回与.then回调中的第一个参数相同的值,我错了吗?”。
不,你是绝对正确的。但是,你在.then回调中的第一个参数是错误的。
您定义myAsyncRequest
返回IHttpPromise<IResp>
。但IHttpPromise<T>
被定义为继承IPromise
方式如下:
type IHttpPromise<T> = IPromise<IHttpPromiseCallbackArg<T>>;
所以,一个IHttpPromise<T>
是返回IHttpPromiseCallbackArg<T>
放回原处T
类型的实际数据是IHttpPromiseCallbackArg<T>
的data
财产的承诺。
因此,旧代码变种,我们在这个问题看:
handleSubmit(form) {
const params = this.getParams(form);
this.myAsyncRequest(params)
.then((resp:IResp) => this.processResp(resp))
.catch((e:IServerError) => this.handleError(e));
}
实际上应该不无打字稿错误时myAsyncRequest
定义为返回IHttpPromise
编译。
HOWTO修复此:
async handleSubmit(form) {
const params = this.getParams(form);
try {
const httpResp:IHttpPromiseCallbackArg<IResp> = await this.myAsyncRequest(params);
const resp: IResp = httpResp.data;
this.processResp(resp);
} catch (e:IServerError) {
this.handleError(e);
}
}
注意:在对角的最新类型定义,类型IHttpPromiseCallbackArg<T>
实际上是所谓IHttpResponse<T>
。
也许在你的代码中,你定义了IResp
为IHttpResponse<Something>
?然后你只是与旧名称IHttpPromiseCallbackArg
发生冲突。然后从DefinitelyTyped获取使用新名称的最新类型定义。而且您还必须将myAsyncRequest
的定义更改为:
myAsyncRequest(params:IParams):IHttpPromise<Something> {
包含await
确实伺机解决线值 - 但是因为函数本身是异步的(允许所有等待的),你会得到一个承诺。
例......在下面的代码,你可以为y
使用x
作为一个普通的数字(尽管delay
回报承诺),并再次 - 所以你等待的东西解决了,所以你可以像你会用这如果它是同步的。
看起来不像它返回承诺的异步函数现在可以实现。
这看起来很让人困惑,因为它似乎“反转了承诺”,但它所做的是将then
转移到顶层(可以将异步函数调用到其他异步函数等等)。
function delay(ms: number) {
return new Promise<number>(function(resolve) {
setTimeout(() => {
resolve(5);
}, ms);
});
}
async function asyncAwait() {
let x = await delay(1000);
console.log(x);
let y = await delay(1000);
console.log(y);
return 'Done';
}
asyncAwait().then((result) => console.log(result));
因此,在一天结束时,我仍然需要在某处调用'.then'? – user2954463
你可能还需要在最上面调用'then'(在某些情况下,你将函数传递给别的东西的时候,你不需要)。 – Fenton
什么是downvote?任何改善答案的建议? –
请提供一个最小的完整示例。 – NineBerry
IHttpPromiseCallbackArg类型不是承诺。这已经是函数调用的实际结果。请参阅http://definitelytyped.org/docs/angular-translate--angular-translate/interfaces/ng.ihttppromisecallbackarg.html – NineBerry
我可以将我的问题改写为 - “我认为await会返回与第一个参数相同的值在'.then'回调中,我错了吗?“ – user2954463