web-dev-qa-db-fra.com

Comment utiliser la méthode $ .post () de jQuery avec async/wait et le manuscrit

Mes instructions wait dans les fonctions asynchrones sont des appels à la méthode $ .post () de jQuery qui renvoient une promesse valide. Cependant, cette erreur se produit dans TypeScript: 

Le type d'opérande 'wait' doit être soit une promesse valide, soit ne pas contenir de membre 'alors' appelable.

Ma fonction est la suivante (simplifié pour l'exemple). Le code est valide et fonctionne, mais je reçois une erreur dans la console 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.....');
    }
  }

J'imagine que TS a un problème avec $ .post () parce que vous pouvez y appeler .then (), mais comment résoudre ce problème? De plus, je n'avais pas cette erreur avant la mise à jour 2.4.2.

7
Amir

Il semble en effet que TypeScript soit gênant pour que jQuery retourne un objet promesse qui est à la fois un objet différé et un objet jqXHR :

Les objets jqXHR renvoyés par $.ajax() à partir de jQuery 1.5 implémentent l'interface Promise en leur donnant toutes les propriétés, méthodes et comportements d'une promesse (voir Objet différé pour plus d'informations).

Il existe au moins trois solutions de contournement à cet entêtement de TypeScript.

Solution renvoyant une pure promesse ES6

Vous pouvez transmettre la valeur de retour à Promise.resolve() , qui renverra une véritable promesse ES6, en promettant la même valeur:

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

Solutions retournant les promesses de jQuery

Les deux autres alternatives ne renvoient pas de pure promesse ES6, mais jQuery, qui est toujours suffisante. Sachez cependant que ces objets de promesse ne sont que des promesses/conformes à A + à partir de jQuery 3 les versions suivantes:

Vous pouvez appliquer la méthode deferred.promise , qui renvoie un objet de promesse jQuery:

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

Vous pouvez également appliquer la méthode deferred.then , qui renvoie également une promesse jQuery:

Depuis jQuery 1.8, la méthode deferred.then() renvoie une nouvelle promesse

En ne fournissant aucun argument à then, vous retournez effectivement une promesse pour la même valeur promise:

postResult = await $.post(postUrl, $.param(postData)).then();
11
trincot

JQueryXHR a sa propre version de .then () qui offre des options supplémentaires:

then<R>(doneCallback: (data: any, textStatus: string, jqXHR: JQueryXHR) => R, failCallback?: (jqXHR: JQueryXHR, textStatus: string, errorThrown: any) => void): JQueryPromise<R>;

Pour utiliser wait dans TypeScript avec $ .post, je devais supprimer cette ligne de jquery.d.ts. TypeScript verra alors le .then défini sur JQueryGenericPromise.

1
libertyernie