Me preguntaba si hay alguna para cancelar/detener la ejecución de una función de javascript que contiene múltiples funciones de espera. Debido a la naturaleza de las promesas y su falta de cancelaciones adecuadas, ¿hay alguna otra implementación o biblioteca que me ayude a lograr algo como esto?
async function run(x,y,z) { return new Promise(async(resolve,reject) => { await doSomething(x) await doSomething(y) //cancel could be happen around here and stop the last "doSomething" await doSomething(z) }) } setTimeout(() => { run.cancel() },500) //cancel function after 500msLa forma de usar realmente la cancelación es a través de AbortController que está disponible en el navegador y en Node 15+
Referencia de nodo: https://nodejs.org/api/globals.html#class-abortcontroller
Referencia de MDN: https://developer.mozilla.org/en-US/docs/Web/API/AbortController
Algunas API están utilizando actualmente la señal de cancelación lista para usar, como buscar en el navegador o configurar la API de temporizadores de tiempo de espera en Node ( https://nodejs.org/api/timers.html#timerspromisessettimeoutdelay-value-options ).
Para las funciones/API personalizadas, debe implementarlas usted mismo, pero se recomienda encarecidamente seguir la metodología de la señal Abort para que pueda encadenar funciones personalizadas y oob y hacer uso de una sola señal que no necesita traducción.
Para simplemente detener el avance de una llamada de función a la siguiente, puede hacer algo como esto:
function run(x, y, z) { let stop = false; async function run_internal() { await doSomething(x) if (stop) throw new Error("cancelled"); await doSomething(y) if (stop) throw new Error("cancelled"); await doSomething(z) } return { cancel: () => { stop = true; }, promise: run_internal(); }; } const retVal = run(a, b, c); retVal.promise.then(result => { console.log(result); }).catch(err => { console.log(err); }) setTimeout(() => { retVal.cancel() }, 500); //cancel function after 500msJavascript no tiene una forma genérica de "abortar" ninguna ejecución posterior de una función. Puede establecer una bandera a través de una función externa y luego verificar esa bandera en varios puntos de su función y ajustar lo que ejecuta en función de esa bandera.
Tenga en cuenta que (excepto cuando use workerThreads o webWorkers), Javascript ejecuta su código en un solo hilo, por lo que cuando se ejecuta, se ejecuta y ninguno de sus otros códigos se ejecuta. Solo cuando devuelve el control al bucle de eventos (ya sea regresando o presionando await ) cualquier otro código tiene la oportunidad de ejecutarse y hacer algo. Entonces, "cuando realmente se está ejecutando", su otro código no se ejecutará. Cuando está sentado en un await , su otro código puede ejecutarse y puede establecer una marca que se puede verificar más tarde (como muestra mi ejemplo anterior).
fetch() en un navegador tiene cierto soporte experimental para la interfaz AbortController. Pero, comprenda que una vez que se haya enviado la solicitud, se enviará y el servidor la recibirá. Es probable que no aborte nada de lo que esté haciendo el servidor. Si la respuesta aún no ha regresado o está en proceso de regresar, su aborto puede interrumpir eso. Dado que realmente no puede saber qué se está abortando, creo que es mejor simplemente marcar su propio código para que no procese la respuesta o avance a un procesamiento posterior en función de una marca que establezca.
Si lo desea, puede incluir esta marca en una interfaz AbortController, pero no cambia el problema fundamental de ninguna manera: solo afecta la API que expone para llamar a un aborto.