Задать вопрос
Forbidden
@Forbidden
CEO, CTO @ a-parser.com

Как снаружи прервать выполнение асинхронной функции?

Всем привет, рассматриваем вопрос о миграции одного проекта с Perl/Coro на nodejs(8.x)/async/await, столкнулись со следующей проблемой:

const snooze = ms => new Promise(resolve => setTimeout(resolve, ms));

let asyncFn = async () => {
    while(1) {
        await snooze(1000);
        console.log(Date.now());
    }
}

let asyncPromise = asyncFn();

setTimeout(() => {
    console.log("try destroy");
    asyncPromise = null;
}, 1500);


Каким образом можно прервать выполнение асинхронной функции? Вариант с внешним флагом не рассматривается по следующей причине:
  • Необходимость прервать выполнение может попасть на долгий sleep и долгую сетевую операцию
  • Постоянная проверка флага перед каждым await убивает всю элегантность решения


В других языках, в частности в Perl/Coro корутину всегда можно прервать или кинуть в нее исключение.
Честно говоря после гугления надежд мало, но все же, есть гуру кто решил эту проблему?
  • Вопрос задан
  • 4735 просмотров
Подписаться 4 Оценить 22 комментария
Пригласить эксперта
Ответы на вопрос 3
Negwereth
@Negwereth
lvivcss.com.ua
throw.
Вызовы при этом надо в try...catch заворачивать.
Ответ написан
Forbidden
@Forbidden Автор вопроса
CEO, CTO @ a-parser.com
Для всех сочувствующих - рекомендую не читать предыдущие комменты, там вы получите батхерд который никак не относится к теме топика

Вот большая дискуссия о включение cancelation в стандарт https://github.com/tc39/ecmascript-asyncawait/issues/27
TL;DR в конце концов там никчему и не пришли

Еще интересные ссылки:
https://github.com/getify/asynquence - библиотека одного из активных комментаторов в том топике, реализует поддержку отмены
https://github.com/JeffreyZhao/windjs.org-cn/blob/... - китайцы реализуют отмену через canelation token(привет C#) в 2012 году

И скорее всего самое главное:
https://github.com/tc39/proposal-cancellation - свежее предложение в стандарт и готовая реализация https://github.com/rbuckton/prex
Ответ написан
SynCap
@SynCap
Делаю интернет с 1998 года
Если флаги не вариант, тогда только запихнуть асинхронную задачу в отдельный процесс - его при желании можно прибить. Для отдельного процесса, можно легко организовать `await`.
Читать тут
Ничего не мешает сделать отдельные самостоятельные модули под асинхронные процессы.
Таким макаром можно организовать аналог многопоточности с балансировкой, контролем приоритетов. чифирем и папиросами.

* npmjs.com/package/invoke-parallel
* npmjs.com/package/runnablepool
* npmjs.com/package/child-pool

Есть еще workers и cluster

И не надо забывать, что вся асинхронность Ноды - на событиях (Event Loop)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы