Существует два типа долгосрочных задач, и отмена для обоих различна:
1) Асинхронные задачи:
Они могут занять некоторое время, однако они не используют движок JavaScript,вместо этого движок находится в режиме ожидания, ожидая каких-то внешних данных (базы данных / файлов / таймеров и т. д.).В некоторых случаях (например, таймеры) вы можете легко отменить это внешнее действие, а также вызвать его как событие, так как двигатель не заблокирован и может обработать отмену.Если асинхронное действие не может быть отменено напрямую (например, чтение базы данных), вы можете подождать, пока оно не будет выполнено, и отменить его:
class Cancelable {
constructor() {
this.cancelled = false;
this.handlers = [];
}
onCancel(handler) { this.handlers.push(handler); }
cancel() {
this.cancelled = true;
this.handlers.forEach(handler => handler());
}
}
// inside of the request handler:
const canceller = new Cancelable;
req.setTimeout(5000, () => {
res.status(503);
res.send();
canceller.cancel(); // propagate cancellation
});
// Some long running, async cancellable task
const timer = setTimeout(function() {
res.send("done");
}, 10000 * Math.random())
// on cancellation just remove the timer
canceller.onCancel(() => clearTimeout(timer));
unCancellableAction(function callback() {
if(canceller.canceled) return; // exit early if it was cancelled
res.send("done");
});
2) Синхронные задачи: вы не можете отменить синхронные задачи напрямую, так как механизм работает.занят выполнением задачи и не может справиться с отменой.Чтобы сделать их отменяемыми, необходимо использовать опрос, задача должна приостановить свою работу, проверить, следует ли ее отменить, а затем продолжить или прервать.В JS это можно сделать с помощью функций генератора (поскольку они могут привести к их выполнению):
function runMax(time, action) {
const gen = action(), start = Date.now();
let done, value;
do {
({ done, value } = gen.next());
} while(!done && Date.now() < start + time)
return value;
}
// inside the request handler:
runMax(5000, function* () {
while(true) {
// ... some jobs
// yield at a safe position to allow abortion:
yield;
}
});