What it's saying is that, by using the code in the example:
setTimeout(() => img.remove(), 3000); // (*)
Using that code exactly, you can't detect when the image gets removed and do something when it occurs - its asynchronous removal is disconnected from the outer Promise chain.
The article's recommendation to fix it is to have the constructed Promise resolve when .remove()
is called:
setTimeout(() => {
img.remove();
resolve(githubUser);
}, 3000);
Or you could put more code inside the setTimeout
to run exactly when the image gets removed.
setTimeout(() => {
img.remove();
console.log('removed');
}, 3000);
If you don't do either of the above, and instead have just the setTimeout(() => img.remove(), 3000);
, the asynchronous action that occurs after 3 seconds can't do anything except remove the image - which is usually a mistake. For example, if you wanted to chain another .then
onto it which runs when the image gets removed, and the image needs to be removed after 3 seconds
.then(() => {
// what logic to put in here to ensure next .then runs after 3 seconds?
setTimeout(() => {
img.remove();
}, 3000);
})
.then(() => {
console.log('image removed');
});
When inside a .then
, to have the next .then
run after a delay, you must return a Promise from the above .then
, and that Promise must resolve after the delay is over.
.then(() => {
// what logic to put in here to ensure next .then runs after 3 seconds?
return new Promise((resolve) => {
setTimeout(() => {
img.remove();
}, 3000);
});
.then(() => {
console.log('image removed');
});
If you don't return a Promise from the upper .then
, or if you don't return anything at all, the lower .then
will run immediately, as soon as the upper .then
finishes, which you don't want.