db2791
db2791

Reputation: 1110

Javascript Race condition for Promises

Let's say I have three async functions:

functionPromise1, functionPromise2, functionPromise3

I want all three to be called concurrently, with the following details:

My use case for these functions is that functionPromise1 serves as an input validation that I want to make synchronous with other functions that treat input as already validated in order to speed up my process. However, if the input is at any point found to be invalid by functionPromise1, I want to terminate the code.

function functionPromise2(...){
    return new Promise(function(resolve,reject){
        fetchUrl(url, function(err, meta, body){
            if (err) { reject(err); } else {
                if (body.toString().indexOf(text) !== -1){
                    resolve();
                } else {
                    reject("Could not find quote");
                }
            }
        });
    });
}

function functionPromise3(...) {
    return new Promise(function(resolve,reject){
        var id = shortid.generate();
        var fileName = id+'.png';
        webshot(url, fileName, { shotOffset: {left: mouseX, top: mouseY} }, function(err) {
            if (err) { reject(err); } else {
                resolve({id: id, fileName: fileName});   
            }
        });
    });
}

Upvotes: 0

Views: 484

Answers (2)

Bergi
Bergi

Reputation: 664513

Regarding the "continue to the next part of the code", you're essentially looking for Promise.all which waits for everything and immediately rejects if there's an error in any promise:

return Promise.all([functionPromise1(), functionPromise2(), functionPromise3()]);

To stop the latter two processes when functionPromise1() rejects, there is nothing that promises can handle for you, you'll need to do that manually.

Upvotes: 2

john_omalley
john_omalley

Reputation: 1398

The answer to this question really depends upon what functionPromise2 and functionPromise3 do. If both simply perform, say, one I/O operation, then you just want to use Promise.all([f1, f2, f3]). If they are more involved (i.e. multiple callbacks) then you would need to keep state somewhere to hold the result from the first promise and check it during the intermediate steps of the second and third promises.

You can't really have true race conditions in single-threaded Javascript. In the interest of simplicity I would make sure the straightforward solution - the Promise.all or f1.then(() => Promise.all([f2, f3]) - was not good enough before making it more complex.

Upvotes: 0

Related Questions