Manera adecuada para Abortar (stop) en ejecución async/await función?

0

Pregunta

Ha habido otros temas en la SE, pero la mayoría de ellos son de fecha 5 de años atrás. ¿Cuál es la actual, up-to-fecha de enfoque para cancelar esperan la llamada en JS? es decir,

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

en el momento específico de la aplicación decide que ya no quiere esperar a que oneHourLastingFunction, pero está atrapado en "esperan". Cómo cancelar? Cualquiera de las formas estándar de cancelación-fichas/abortControllers promesas?

1

Mejor respuesta

1

La cancelación de un procedimiento asincrónico, todavía no es una tarea trivial, especialmente cuando usted necesita profundo cancelación y control de flujo. No hay ninguna solución nativa en el momento. Todo lo que puedes hacer de forma nativa:

  • pasar AbortController instancia para cada anidada async función que desea hacer cancelables
  • suscribir todos interno de micro-tareas (solicitudes, temporizadores, etc) a la señal de
  • opcionalmente darse de baja completado micro-tareas de la señal
  • llame abort método del controlador para cancelar todas las suscrito micro-tareas

Esto es bastante detallado y una difícil solución con potencial de pérdidas de memoria.

Sólo puedo sugerir mi propia solución a este reto- c-promise2, que proporciona cancelable promesas y un cancelable alternativa para ECMA asincrónica funciones - generadores.

Aquí es un ejemplo básico (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();

Profundamente cancelables solución (todas las funciones son rescindibles) (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

En otros idiomas

Esta página está en otros idiomas

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