web-dev-qa-db-ja.com

async / awaitとtypescriptでjQueryの$ .post()メソッドを使用する方法

非同期関数内の私のawaitステートメントは、有効なpromiseを返すjQueryの$ .post()メソッドの呼び出しですが、TypeScriptでこのエラーが発生しています:

「await」オペランドのタイプは、有効なプロミスであるか、呼び出し可能な「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は.then()を呼び出すことができるため、$。post()に問題があると推測していますが、この問題を回避するにはどうすればよいですか?また、2.4.2を更新する前にこのエラーはありませんでした。

12
Amir

TypeScriptは、jQueryが 遅延オブジェクトとjqXHRオブジェクト の両方であるpromiseオブジェクトを返すことに関して厄介なようです。

JQuery 1.5の$.ajax()によって返されるjqXHRオブジェクトはPromiseインターフェイスを実装し、Promiseのすべてのプロパティ、メソッド、および動作を提供します(詳細については Deferred object を参照)。

TypeScriptのこの頑固さに少なくとも3つの回避策があります

純粋なES6 Promiseを返すソリューション

戻り値を Promise.resolve() に渡すと、同じ値を約束する真のES6 Promiseが返されます。

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

JQuery Promiseを返すソリューション

他の2つの選択肢は、純粋なES6 Promiseを返しませんが、jQuery Promiseを返しますが、それでも十分です。ただし、これらのpromiseオブジェクトはPromises/A +にのみ準拠していることに注意してください jQuery 3から 以降:

_deferred.promise_ method を適用すると、jQuery promiseオブジェクトが返されます。

_postResult = await $.post(postUrl, $.param(postData)).promise();
_

または、jQuery promiseを返す _deferred.then_ method を適用することもできます。

JQuery 1.8では、deferred.then()メソッドは新しいpromiseを返します

thenに引数を指定しないことにより、同じpromised値のpromiseを効果的に返します。

_postResult = await $.post(postUrl, $.param(postData)).then();
_
12
trincot

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を確認します。

1
libertyernie