Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how about add a way to interrupt the loop from outside? #7

Open
franckchen opened this issue Aug 3, 2022 · 5 comments
Open

how about add a way to interrupt the loop from outside? #7

franckchen opened this issue Aug 3, 2022 · 5 comments

Comments

@franckchen
Copy link

Currently only provides a way to break the loop internally by return end symbol, It would be useful to provide a way to cancel the loop from outside like below.

const cancellablePromise = pForever(async () => {
});

cancellablePromise.cancel();

why i need to cancel a promise from outside? bcz code like below is stupid.😓

let loopShouldStop = false;

pForever(async () => {
     if (loopShouldStop) return pForever.end;
     await doJobA();
     if (loopShouldStop) return pForever.end;
     await doJobB();
     if (loopShouldStop) return pForever.end;
     await doJobC();
});
@sindresorhus
Copy link
Owner

I don't see how that could work. pForever cannot interrupt the async function you provide. There's no native async cancellation in JavaScript.

@sindresorhus
Copy link
Owner

However, we should improve the usability for this specific case.

Braindump: We could maybe add a pForever.endIf() (needs a better name) method, that would accept a boolean for whether to end, and if true or left out, would throw and error that made pForever stop.

Which would look like:

let loopShouldStop = false;

pForever(async () => {
	pForever.endIf(loopShouldStop);
	await doJobA();
	pForever.endIf(loopShouldStop);
	await doJobB();
	pForever.endIf(loopShouldStop);
	await doJobC();
});

I'm also open to other ideas.

@franckchen
Copy link
Author

franckchen commented Aug 4, 2022

too may pForever.endIf maybe not elegant enough.🤔
I think promise-fun similar to caolan / async, so how about like this.

pForever(
    [
        asyncJobA,
        asyncJobB,
        async () => {
            // some asyn job
        },
        () => {
            // do some sync job
        }
    ],
    () => {
        //  Execute the next task if the condition is true, otherwise, end the loop
        return condition;
    }
)

Also I don't want to wait for the asynchronous task to finish, I want to terminate it immediately.This is a very common requirement in actual development

const promise = pForever(async (onCancel) => {
    let p;
    onCancel(() => p?.cancel());

    p = doJobA();
    await p;
    p = doJobB();
    await p;
    p = doJobC();
    await p;
});

promise.cancel();

@sindresorhus
Copy link
Owner

The proper solution these days is to use AbortController, so it would be something like this if pForever supported it:

const promise = pForever({signal}, async signal => {
	await doJobA({signal});
	await doJobA({signal});
	await doJobA({signal});
});

@mahnunchik
Copy link

It would be helpful to have AbortController be added

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants