Bonne façon de faire Avorter (stop) en cours d'exécution async/await fonction?

0

La question

Il y a d'autres sujets sur SOI, mais la plupart d'entre eux sont datées d'il y a 5 ans. Qu'est-ce que le courant, jusqu'à la date approche à annuler attendent appel en JS? c'est à dire

async myFunc(){
    let response = await oneHourLastingFunction();
    myProcessData(response);
}

au moment précis de l'application décide qu'il ne veut plus attendre que oneHourLastingFunctionmais il est coincé dans les "en attente". Comment l'annuler? De toute façon standard d'annulation-les jetons/abortControllers pour des promesses?

1

La meilleure réponse

1

Annulation d'une procédure asynchrone est toujours pas une tâche facile, surtout quand vous avez besoin profond d'annulation et de contrôle de flux. Il n'y a pas de solution native pour le moment. Tout ce que vous pouvez faire nativement:

  • passer AbortController instance à chaque imbriquée asynchrone en fonction que vous voulez faire annulable
  • s'abonner à tous les micro-tâches (les demandes, les timers, etc) pour le signal
  • en option de désabonnement rempli de micro-tâches à partir du signal
  • appel abort la méthode du contrôleur pour annuler tous les abonnés de micro-tâches

C'est assez verbeux et un délicat solution à d'éventuelles fuites de mémoire.

Je peux vous proposer mon propre solution à ce défi- c-promise2, qui offre annulable promesses et annulable alternative pour l'ECMA asynchrone des fonctions génératrices.

Voici un exemple de base (Démo):

import { CPromise } from "c-promise2";

// deeply cancelable generator-based asynchronous function
const oneHourLastingFunction = CPromise.promisify(function* () {
  // optionally just for logging
  this.onCancel(() =>
    console.log("oneHourLastingFunction::Cancel signal received")
  );
  yield CPromise.delay(5000); // this task will be cancelled on external timeout
  return "myData";
});

async function nativeAsyncFn() {
  await CPromise.delay(5000);
}

async function myFunc() {
  let response;
  try {
    response = await oneHourLastingFunction().timeout(2000);
  } catch (err) {
    if (!CPromise.isCanceledError(err)) throw err;
    console.warn("oneHourLastingFunction::timeout", err.code); // 'E_REASON_TIMEOUT'
  }
  await nativeAsyncFn(response);
}

const nativePromise = myFunc();

Profondément résiliable solution (toutes les fonctions sont annulables) (Démo):

import { CPromise } from "c-promise2";

// deeply cancelable generator-based asynchronous function
const oneHourLastingFunction = CPromise.promisify(function* () {
  yield CPromise.delay(5000);
  return "myData";
});

const otherAsyncFn = CPromise.promisify(function* () {
  yield CPromise.delay(5000);
});

const myFunc = CPromise.promisify(function* () {
  let response;
  try {
    response = yield oneHourLastingFunction().timeout(2000);
  } catch (err) {
    if (err.code !== "E_REASON_TIMEOUT") throw err;
    console.log("oneHourLastingFunction::timeout");
  }
  yield otherAsyncFn(response);
});

const cancellablePromise = myFunc().then(
  (result) => console.log(`Done: ${result}`),
  (err) => console.warn(`Failed: ${err}`)
);

setTimeout(() => {
  console.log("send external cancel signal");
  cancellablePromise.cancel();
}, 4000);
2021-11-25 16:48:29

Dans d'autres langues

Cette page est dans d'autres langues

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................