Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

It is possible to remove a promise from an array of promise?

I want to create somthing like that handle synchronous behavior and asynchronous behavior at the same time. For example I would like to be able something like that :

function timeout(myJson) {
    return new Promise(function (resolve, reject) {
        setTimeout(resolve, myJson.wait, myJson);
    });
}

async function funct() {
    try {
        let PromiseTolaunch = [{ "wait": 10, "nextIndex": 2, "id": 1 }, 
                                { "wait": 500, "nextIndex": -1, "id": 2 }, 
                                { "wait": 5, "nextIndex": -1, "id": 3 }];
        let launchedPromise = [], finishedPromise;

        launchedPromise.push(timeout(PromiseTolaunch[0]));
        launchedPromise[0].id = PromiseTolaunch[0].id;
        launchedPromise.push(timeout(PromiseTolaunch[1]));
        launchedPromise[1].id = PromiseTolaunch[1].id;
        while (launchedPromise.length !== 0) {
            finishedPromise = await Promise.race(launchedPromise);
        [*] console.log(finishedPromise); // Expected output: { "wait": 10, "nextIndex": 2 } 
            //console.log(launchedPromise); // Expected output : [Promise { { wait: 10, nextIndex: 2, id: 1 }, id: 1 }, Promise { <pending>, id: 2 } ]

            //I want to :
            //Remove the promise that just been executed from launchedPromise

            //console.log(launchedPromise); // Expected output : [ Promise { <pending>, id: 2 } ]
            if (finishedPromise.nextIndex !== -1) {
                launchedPromise.push(timeout(PromiseTolaunch[finishedPromise.nextIndex]));
            }
        }
        return Promise.resolve("done")
    } catch (error) {
        return Promise.reject(error);
    }
}

Here i want to remove the promise that returned finishedTest from lunchedPromise What I already tried :

launchedPromise.splice( lunchedTests.indexOf(finishedTest), 1 );
launchedPromise = lunchedTests.filter(prom => prom !== finishedTest);

And it obviously does not work because (finishedTest !== PromiseToLunch[0]) It is not even the same type but I needed to test ^^. I also tried to access to PromiseValue without sucess.

If we conserve only the console.log() that is mark by a [*]. I would like to get the following output :

{ "wait": 10, "nextIndex": 2, "id": 1 }  
{ "wait": 5, "nextIndex": -1, "id": 3 }]
{ "wait": 500, "nextIndex": -1, "id": 2 }
like image 953
Adrien CROSIO Avatar asked Dec 12 '19 16:12

Adrien CROSIO


People also ask

Is it possible to cancel a Promise?

In modern JavaScript - no Promises have settled (hah) and it appears like it will never be possible to cancel a (pending) promise. Instead, there is a cross-platform (Node, Browsers etc) cancellation primitive as part of WHATWG (a standards body that also builds HTML) called AbortController .

How do you deal with an array of Promises?

Given an array of Promises, we have to run that in a series. To do this task, we can use then(), to run the next promise, after completion of a promise. Approach: The then() method returns a Promise, which helps us to chain promises/methods.

Does Promise all cancel other Promises?

Promise.all is rejected if any of the elements are rejected. For example, if you pass in four promises that resolve after a timeout and one promise that rejects immediately, then Promise.all will reject immediately.

Can you resolve a Promise with a Promise?

Resolving a promise to another promise will automatically make it wait for the other promise's result. This is what makes promises chainable (returning further promises in then() callbacks).


1 Answers

So, the answer to this post is this function:

for (let i = 0; i < LaunchedTests.length; i++) {
    if (LaunchedTests[i].id === finishedTest.scenario + finishedTest.name) {
        return Promise.resolve(LaunchedTests.splice(i, 1));
    }
}
return Promise.reject("not find");

But first you need to initialise an id like that:

let PromiseTolaunch = [{ "wait": 10, "nextIndex": 2, "id": 1 }, 
                       { "wait": 500, "nextIndex": -1, "id": 2 }, 
                       { "wait": 5, "nextIndex": -1, "id": 3 }];
let launchedPromise = [], finishedPromise;
launchedPromise.push(timeout(PromiseTolaunch[0]));
launchedPromise[0].id = PromiseTolaunch[0].id;
launchedPromise.push(timeout(PromiseTolaunch[1]));
launchedPromise[1].id = PromiseTolaunch[1].id;

Your promise will have this form: Promise { <pending>, id: YourId } and you would be able to access to it through passing by the findIndex() function and you just have to splice it.

Thanks to @dx-over-dt and everyone for helping me !

like image 149
Adrien CROSIO Avatar answered Oct 18 '22 09:10

Adrien CROSIO