我在async函数中的await语句是对jQuery的$ .post()方法的调用,该方法返回一个有效的promise,但是我在TypeScript中遇到了这个错误:
'await'操作数的类型必须是有效的promise或者不能包含可调用的'then'成员。
我的功能是这个(示例简化)。代码有效且有效,但我在TS控制台中收到错误。
async function doAsyncPost() {
const postUrl = 'some/url/';
const postData = {name: 'foo', value: 'bar'};
let postResult;
let upateResult;
function failed(message: string, body?: string) {
console.log('error: ', message, ' body: ', body);
}
function promiseFunc() {
return new Promise<void>( resolve => {
// ... do something else....
resolve();
});
};
function finish() {
// ... do something at the end...
}
try {
// The error is on the $.post()
postResult = await $.post(postUrl, $.param(postData));
if (postResult.success !== 'true') {
return failed('Error as occoured', 'Description.....');
}
await promiseFunc();
return finish();
} catch (e) {
await failed('Error as occoured', 'Description.....');
}
}
我猜TS有$ .post()的问题,因为你可以调用.then(),但是如何解决这个问题呢?另外,在更新2.4.2之前我没有出现此错误。
答案 0 :(得分:11)
看起来确实TypeScript对于jQuery返回一个同时为a deferred and a jqXHR object的promise对象感到讨厌:
jQuery 1.5中
$.ajax()
返回的jqXHR对象实现了Promise接口,为它们提供了Promise的所有属性,方法和行为(有关详细信息,请参阅Deferred object)。
TypeScript
的这种顽固性至少有三种解决方法你可以将返回值传递给Promise.resolve()
,这将返回一个真正的ES6 Promise,承诺相同的值:
postResult = await Promise.resolve($.post(postUrl, $.param(postData)));
另外两个选择不会返回纯ES6承诺,但jQuery承诺,仍然足够好。请注意,这些承诺对象仅符合Promise / A + from jQuery 3以后的要求:
您可以应用deferred.promise
method,它返回一个jQuery promise对象:
postResult = await $.post(postUrl, $.param(postData)).promise();
或者,您可以应用deferred.then
method,它也会返回一个jQuery承诺:
从jQuery 1.8开始,
deferred.then()
方法返回一个新的承诺
通过不向then
提供任何参数,您实际上会返回相同承诺值的承诺:
postResult = await $.post(postUrl, $.param(postData)).then();
答案 1 :(得分:1)
JQueryXHR有自己的.then()版本,它有一些额外的选项:
then<R>(doneCallback: (data: any, textStatus: string, jqXHR: JQueryXHR) => R, failCallback?: (jqXHR: JQueryXHR, textStatus: string, errorThrown: any) => void): JQueryPromise<R>;
要在TypeScript中使用带有$ .post的await,我必须从jquery.d.ts中删除该行。然后TypeScript将看到在JQueryGenericPromise上定义的.then。