Modo corretto di Interruzione (stop) in esecuzione async/await funzione?

0

Domanda

Ci ha altri argomenti in SE, ma la maggior parte di loro sono datate 5 anni fa. Qual è l'attuale, up-to-data approccio per annullare attendono la chiamata in JS? cioè

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

al momento applicazione che decide di non voler più aspettare che oneHourLastingFunctionma si è bloccato in "attesa". Come annullare? Qualsiasi modalità standard di cancellazione-gettoni/abortControllers per promesse?

1

Migliore risposta

1

Annullamento di una procedura asincrona non è ancora un compito facile, specialmente quando si ha bisogno profondo di cancellazione e di controllo di flusso. Non c'è una soluzione nativa al momento. Tutto si può fare in modo nativo:

  • passare AbortController istanza per ciascun nidificati async funzione che si desidera rendere annullabile
  • iscriviti all interno di micro-attività (richieste, timer, ecc) per il segnale
  • facoltativamente annullare completato micro-attività dal segnale
  • chiamata abort metodo del controller per annullare tutti i sottoscritto micro-attività

Questo è molto dettagliato e di difficile soluzione con un potenziale di perdite di memoria.

Posso solo suggerire la mia soluzione a questa sfida- c-promise2, che fornisce annullabile promesse e cancellabile alternativa per ECMA funzioni asincrone - generatori.

Qui è un esempio di base (Live Demo):

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();

Profondamente annullabile soluzione (tutte le funzioni sono annullabili) (Live Demo):

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

In altre lingue

Questa pagina è in altre lingue

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