我想将一个promise链重构为async / await,但是Typescript抱怨打字。
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);
}
如果我删除&#34; IResp&#34;从const resp声明中,processResponse抱怨IHttp&lt; IResp&GT;不等于IResp ...
processResp(resp:IResp) {
//do stuff
}
答案 0 :(得分:4)
你的问题“我认为await将返回与.then回调中的第一个参数相同的值。我错了吗?”。
不,你是对的。但你对.then回调中的第一个参数是错误的。
您定义myAsyncRequest
以返回IHttpPromise<IResp>
。但IHttpPromise<T>
被定义为以下列方式继承IPromise
:
type IHttpPromise<T> = IPromise<IHttpPromiseCallbackArg<T>>;
因此,IHttpPromise<T>
是一个返回IHttpPromiseCallbackArg<T>
的承诺,其中T
类型的实际数据位于data
的{{1}}属性中
所以,我们在问题中看到的旧代码变体:
IHttpPromiseCallbackArg<T>
当handleSubmit(form) {
const params = this.getParams(form);
this.myAsyncRequest(params)
.then((resp:IResp) => this.processResp(resp))
.catch((e:IServerError) => this.handleError(e));
}
被定义为返回myAsyncRequest
时,实际上不应该在TypeScript中编译而没有错误。
如何解决这个问题:
IHttpPromise
注意:在角度的最新类型定义中,类型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>
发生冲突。然后从DefinitelyTyped获取使用新名称的最新类型定义。而且您还必须将IHttpPromiseCallbackArg
的定义更改为:
myAsyncRequest
答案 1 :(得分:-1)
包含await
的行确实等待已解析的值 - 但由于函数本身是异步的(允许所有等待的),您将获得一个承诺。
示例...在下面的代码中,您可以使用x
作为普通数字(即使delay
返回承诺),也可以使用y
- 所以您等待的所有内容已经解决了,所以你可以像使用同步一样使用它。
async函数似乎不会返回一个promise,现在就是。
这看起来有点令人困惑,因为它似乎反转了承诺&#34;但它的作用是将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));