The most surprising thing that's bitten me about async/await is that the promise is immediately executed rather than being executed at the point they get awaited.
If you don't want to continue with something inside a Promise, just pass in something that could be changed from `true` to `false` and it cancels itself based on that.
Regarding other cases, there are already ways of handling those. I don't think just because many ask about something, doesn't mean it's not currently working.
controller = new AbortController();
const signal = controller.signal;
fetch("http://example.com", { signal: signal })
// abort request
controller.abort();
It basically couldn't be simpler? What sort of API would you like to be able to cancel requests?Here is the implementation I typically use for doing just that:
async function executeQueue(promises, concurrentLimit) {
let index = 0;
let activePromises = [];
async function manageQueue() {
if (index >= promises.length && activePromises.length === 0) return;
while (activePromises.length < concurrentLimit && index < promises.length) {
const promise = promises[index]();
activePromises.push(promise);
index++;
promise.then(() => {
activePromises = activePromises.filter(p => p !== promise);
manageQueue();
});
}
}
await manageQueue();
await Promise.all(activePromises);
}
Used like this: function r(i, resolve) {
console.log(`Task ${i}`)
resolve(`Task ${resolve}`)
}
// Example usage
const promises = [
() => new Promise(resolve => setTimeout(() => r("Task 1", resolve), 2000)),
() => new Promise(resolve => setTimeout(() => r("Task 2", resolve), 1000)),
() => new Promise(resolve => setTimeout(() => r("Task 3", resolve), 3000)),
() => new Promise(resolve => setTimeout(() => r("Task 4", resolve), 500)),
() => new Promise(resolve => setTimeout(() => r("Task 5", resolve), 1500))
];
executeQueue(promises, 4).then(() => {
console.log("All tasks completed!");
});
Would print: "Task Task 4"
"Task Task 2"
"Task Task 1"
"Task Task 5"
"Task Task 3"
"All tasks completed!"