Nicholas Robinson Nicholas Robinson - 7 months ago 22
Javascript Question

Do promises resolve asynchronously or synchronously?

I have been working with JavaScript promises recently and came across the following situation that got me thinking:

var combinedArray = [];

function getArrayOne() {
$http.post(arrayOnePath).then(function(arr) {
combinedArray = combinedArray.concat(arr);
}) // More code preventing me from using Promise.all(...)
}

function getArrayTwo() {
$http.post(arrayTwoPath).then(function(arr) {
combinedArray = combinedArray.concat(arr);
}) // More code preventing me from using Promise.all(...)
}

function getAllArrays() {
getArrayOne();
getArrayTwo();
}


While I was writing this logic it dawned on me that there could be a potential race condition if both promises resolve at the same time (as they access a shared resource). After thinking about this for a little while longer I realized that the
then(..)
resolutions are executing after the post returns which means this code is running in JavaScript's synchronous execution environment.

Could someone please provide some clarity for me on whether the two
combinedArray.concat(arr);
statements could cause a problem if both promises resolve at the same time?

[Edit]
Following some of the comments I just want to add that I don't mind what order the arrays are concatenated into
combinedArray
.

Answer

JavaScript is single-threaded, preventing race conditions even when running asynchronous calls.

There are cases where JS will use another thread in the background, like node's I/O functions, and the web worker API allows you to spawn an isolated but seperate thread (no memory access but they can pass messages).

Because JS was originally single-threaded and everything in the runtime depends on that (and old code assumes it), they can't just add multi-threading and the potential race conditions. It would break everything. So this code will always work correctly and safely, as the promises will be added to a single queue and resolve one after another.

Even in web workers (and the node equivalent), each "thread" has an isolated memory space and cannot directly access variables from another thread. Web workers specifically use a postMessage method to serialize objects and send them to another thread in a safe manner.