如何在async / await和typescript中使用jQuery的$ .post()方法

时间:2017-07-24 17:43:08

标签: jquery typescript es6-promise

我在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之前我没有出现此错误。

2 个答案:

答案 0 :(得分:11)

看起来确实TypeScript对于jQuery返回一个同时为a deferred and a jqXHR object的promise对象感到讨厌:

  

jQuery 1.5中$.ajax()返回的jqXHR对象实现了Promise接口,为它们提供了Promise的所有属性,方法和行为(有关详细信息,请参阅Deferred object)。

TypeScript

的这种顽固性至少有三种解决方法

返回纯ES6承诺的解决方案

你可以将返回值传递给Promise.resolve(),这将返回一个真正的ES6 Promise,承诺相同的值:

postResult = await Promise.resolve($.post(postUrl, $.param(postData)));

返回jQuery承诺的解决方案

另外两个选择不会返回纯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。