This approach aims to prevent the complications that may arise from a long promise chain, especially when it exceeds a length of 15 promises.
Consider implementing the synchronization queue solution by utilizing syncArray
. This queue ensures that any pending asynchronous requests are placed in order and processed based on a first come, first served basis.
If a request has not been processed from the queue, it can be pushed into the queue using the following line:
if(!isProcessFromQueue) {
syncArray.push({query:query, pause:pause});
}
In case a request is already being processed, a delay of 1 second is introduced before attempting to process from the queue again:
if(isRunning) {
setTimeout(function() {
test(null, null, true);
}, 1000);
return;
}
If the queue is empty, the function will terminate at this step:
if(syncArray.length < 1) {
return;
}
Upon completion of an asynchronous request, if the queue still contains items, another processing call from the queue is made while updating the isRunning
status to false
to indicate the previous request's completion:
isRunning = false;
if(syncArray.length > 0) {
test(null, null, true);
}
Below depicts the complete code snippet:
var testDiv = document.getElementById('test');
function loadData(query, pause) {
var data = query;
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve(data);
}, pause);
});
}
var syncArray = [];
var concatData = "";
var isRunning = false;
var test = function(query, pause, isProcessFromQueue) {
if(!isProcessFromQueue) {
syncArray.push({query:query, pause:pause});
}
if(isRunning) {
setTimeout(function() {
test(null, null, true);
}, 1000);
return;
}
if(syncArray.length < 1) {
return;
}
var popedItem = syncArray.shift();
isRunning = true;
loadData(popedItem.query, popedItem.pause)
.then(function(data) {
console.log("got back test data", data);
concatData = concatData + "<br>" + data;
testDiv.innerHTML = concatData;
isRunning = false;
if(syncArray.length > 0) {
test(null, null, true);
}
});
};
test("first", 1000, false);
test("second", 0, false);
test("third", 500, false);
test("forth", 0, false);
<div id="test">
</div>
At present, cancellation of promises is not supported in the current Promise
implementation. However, there are plans for its inclusion in future releases.
For achieving this functionality, consider utilizing third-party library bluebird
. The use of Promise.race
could also be beneficial in certain scenarios.
The Promise.race
setup is outlined below:
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 500, 'one');
});
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'two');
});
Promise.race([p1, p2]).then(function(value) {
console.log(value); // "two"
// Both resolve, but p2 is faster
});