Difference Between Run Sequence Promises By Creating A New Promise Then Run And Creating All Promises Then Run Each
Solution 1:
You have sequenced your timers in "way 1" (they each fire a second apart) and run your timers in parallel in "way 2" so the timers all fire at about the same time. Here's the more detailed explanation:
In "way 1", you create a chain of promises with sequence = sequence.then()
and the setTimeout()
is called from within the sequence. So, timer 2 won't start until after timer 1 fires and so on. You will get each individual timer running truly sequential with each firing about 1 second apart.
In "way 2", you start all the timers at once in your .map()
, so all the timers run in parallel, not in sequence. You are then trying to force them into a sequence with your sequence2 = sequence2.then()
loop, but the async operations were already started in parallel so all this sequential loop doesn't really accomplish anything more than a Promise.all()
would in terms of timing.
If you run each of these two snippets, they will log exactly when the timers fire and you can see the difference between the two.
Here, in a version of "way 1" that logs the time sequence of each timer, you can see the timers firing about 1 second apart:
// way 1let startTime = Date.now();
functionlog() {
let args = Array.from(arguments);
// calc time since startTimelet delta = (Date.now() - startTime) / 1000;
args.unshift(delta + ": ");
console.log.apply(console, args);
}
functiondelay(t, val) {
returnnewPromise(resolve => {
setTimeout(() => {
log("timer fire");
resolve(val);
}, t);
});
}
// Way 1let sequence = Promise.resolve();
[1,2,3,4].forEach((val)=> {
sequence = sequence.then(()=> {
returndelay(1000, val);
}).then(console.log);
});
sequence.then(() => {
log("all done");
})
Here, in a version of "way 2" that logs the time sequence of each timer, you can see the timers firing at all about the same time:
// way 2let startTime = Date.now();
functionlog() {
let args = Array.from(arguments);
// calc time since startTimelet delta = (Date.now() - startTime) / 1000;
args.unshift(delta + ": ");
console.log.apply(console, args);
}
functiondelay(t, val) {
returnnewPromise(resolve => {
setTimeout(() => {
log("timer fire");
resolve(val);
}, t);
});
}
//Way 2let sequence2 = Promise.resolve();
[5,6,7,8].map(val => {
returnnewdelay(1000, val);
}).forEach(promise => {
sequence2 = sequence2.then(() => promise).then(console.log);
});
sequence2.then(() => {
log("all done");
});
When running each snippet, not in particular the time it takes to get to the "all done" message. The first one serializes four one second timers so it takes about 4 seconds to run. The second one runs all the timers in parallel so it takes about 1 second to run.
Additional explanation:
When you do this:
let arrayOfPromoises = [5,6,7,8].map(val => {
returnnewPromise(resolve =>setTimeout(resolve, 1000, val));
});
That code executes return new Promise(resolve => setTimeout(resolve, 1000, val));
four times in a row, one right after the other with no delays. Since each time that code is execute, it creates a new Promise
object, you end up with an array of four promises.
Now, inside of that code you have this:
newPromise(resolve =>setTimeout(resolve, 1000, val));
The Promise executor function (that's what the callback is called that you pass to the Promise constructor) is called IMMEDIATELY. There is no waiting. So, not only have you created four promises, but you've also started four times that are all running at once. These timers are already started. No amount of structuring with your sequence2 = sequence2.then()
loop will change that. The timers are already running.
Solution 2:
To understand this you need to understand that a promise just wait's for something to resolve, so until a resolve is got the following (.then) code chain wont execute
For the first, way lets use different variables instead of the same sequence variable, then the code becomes.
var firstSequence = Promise.resolve()
.then(()=> {returnnewPromise(resolve =>setTimeout(resolve, 1000, 1))})
.then(console.log);
var secondSequence = firstSequence
.then(()=> {returnnewPromise(resolve =>setTimeout(resolve, 1000, 2))})
.then(console.log);
var thirdSequence = secondSequence
.then(()=> {returnnewPromise(resolve =>setTimeout(resolve, 1000, 3))})
.then(console.log);
var foruthSequence = thirdSequence
.then(()=> {returnnewPromise(resolve =>setTimeout(resolve, 1000, 4))})
.then(console.log);
from this you can see that the timeout calls do not happen before a promise is resolved. So they appear to be sequential and they keep getting pushed to wait for one second.
But the second form is equivalent to this.
functionmakePromise(val) {
returnnewPromise(resolve =>setTimeout(resolve, 1000, val));
}
var storageArray = [makePromise(1), makePromise(2), makePromise(3),
makePromise(4)];
we have already pushed all the setimout calls together in one go, so after one second all promises are already resolved. so (.then) wont need to wait wait.
var firstSequence = Promise.resolve()
.then(()=> {return storageArray[0]})
.then(console.log);
var secondSequence = firstSequence
.then(()=> {return storageArray[1]})
.then(console.log);
var thirdSequence = secondSequence
.then(()=> {return storageArray[2]})
.then(console.log);
var foruthSequence = thirdSequence
.then(()=> {return storageArray[3]})
.then(console.log);
So even though they appear to be similar to the first syntax the promises are all, already resolved so no need to wait.
Post a Comment for "Difference Between Run Sequence Promises By Creating A New Promise Then Run And Creating All Promises Then Run Each"