M
M
Mikhail Yurievich2017-07-17 06:43:51
JavaScript
Mikhail Yurievich, 2017-07-17 06:43:51

How to interrupt the execution of an asynchronous function from the outside?

Hello everyone, we are considering the issue of migrating one project from Perl / Coro to nodejs (8.x) / async / await, we encountered the following problem:

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

How can you interrupt the execution of an asynchronous function? The option with an external flag is not considered for the following reason:
  • The need to interrupt the execution can fall into a long sleep and a long network operation
  • Constantly checking the flag before each await kills all the elegance of the solution

In other languages, in particular in Perl / Coro, a coroutine can always be interrupted or an exception thrown into it.
To be honest, after googling, there is little hope, but still, is there a guru who solved this problem?

Answer the question

In order to leave comments, you need to log in

4 answer(s)
N
Negwereth, 2017-07-17
@Negwereth

throw.
Calls should be wrapped in try...catch.

M
Mikhail Yurievich, 2017-08-02
@Forbidden

For all the sympathizers - I recommend not to read the previous comments, there you will get a butthead that is in no way related to the topic topic.
Here is a big discussion about the inclusion of cancelation in the standard in the end, nothing came up there. More interesting links: https://github.com/getify/asynquence - the library of one of the active commentators in that topic, implements cancellation support https://github.com/JeffreyZhao/windjs.org-cn /blob/... - Chinese implement cancellation via canelation token (hello C#) in 2012
https://github.com/rbuckton/prex

K
Konstantin   , 2017-07-27
@SynCap

If flags are not an option, then just shove the asynchronous task into a separate process - you can beat it if you wish. For a single process, you can easily organize `await`.
Read here
Nothing prevents you from making separate independent modules for asynchronous processes.
In this way, you can organize an analogue of multithreading with balancing, priority control. chifire and cigarettes.
* npmjs.com/package/invoke-parallel
* npmjs.com/package/runnablepool
* npmjs.com/package/child-pool
There are also workers and cluster
And don't forget that all Node asynchrony is based on events (Event Loop)

G
Grigory Vasilkov, 2017-09-15
@gzhegow

Do it on Promise();
Then you just need to throw the Promise out and call Promise.resolve() in another thread; and it will not be necessary to wait until the first thread calls.
You will have to revise the logic a little, but it will come out something like this:
1. You are waiting for some result or error from the promise
2. Something happened in another thread that requires you to finish the action. You return a reject with an array from another thread, in the first parameter the error code, in the second a message.
You work as if you received this data from the main promise, it will not resolve twice and will not be re-jacked.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question