<p><pre><code> check()
.then(result => {
if (result) {
// set state to finished
}
check()
.then(result => {
if (result) {
// set state to finished
}
check()
.then(result => {
if (result) {
// set state to finished
}
check()
.then(result => {
if (result) {
// set state to finished
}
check()
.then(result => {
if (result) {
// set state to finished
}
// set state to not done
})
.catch(error => // set state to failed);
})
.catch(error => // set state to failed);
})
.catch(error => // set state to failed);
})
.catch(error => // set state to failed);
})
.catch(error => // set state to failed);
</code></pre>
For the love of everything that’s sacred, please don’t do this. The strength of promises is that they can free us from that exact kind of callback hell, and they do that by being chainable.<p><pre><code> const resultOrNull = await Promise.resolve(null).
then(result => result || check()).
then(result => result || check()).
then(result => result || check()).
then(result => result || check()).
then(result => result || check()).
catch(error => null);
</code></pre>
Calling .then/.catch inside of a .then/.catch is a huge red flag. Almost always, you want to return the promise and chain instead.
There should be some review process for these .christmas articles. I get it - creating tons of articles quickly is hard, but the core message should not be incorrect.<p>I tried to look up a github reference on the page, so I could send a PR to fix the linked article, but it is not available.
Presumably the "// set state to finished" involves a return statement, otherwise "check()" will continue to be called and ultimately the state will be set back to not done. This applies to both the async version and the chain() version. Personally I find it confusing that the comment hides a control flow statement when the text of the comment suggests that it's just setting a state variable.<p>Surely a better comparison for the async function would be a chain() that manually recreates the loop using a parameter or local captured variable, like shown below. They're still complex but if anything show the complexity more clearly, especially if 6 is not hardcoded but could be passed as a parameter. I suppose having the unrolled version from the article plus one of these would be best of all, to show the problem from all angles.<p><pre><code> function chainWithParam() {
var checkAndIterate;
checkAndIterate = (result, i) => {
if (result) {
// set state to finished
return;
}
if (i == 6) {
// set state to not done
return;
}
check()
.then(result => checkAndIterate(result, i + 1))
.catch(error => /* set state to failed */);
}
checkAndIterate(false, 0);
}
function chainWithCapturedLocal() {
i = 0;
var checkAndIterate;
checkAndIterate = result => {
if (result) {
// set state to finished
return;
}
if (i == 6) {
// set state to not done
return;
}
++i;
check()
.then(checkAndIterate)
.catch(error => /* set state to failed */);
}
checkAndIterate(false);
}
</code></pre>
I'm not a JavaScript programmer so there could be mistakes in the above code. I'd be interested to know if there is, especially whether it was really necessary to declare the checkAndIterate variable on a separate line to its assignment.<p>Surely the "manual" function could be implemented with some sort of loop-like
I appreciate that the author is trying to illustrate something with an intentionally contrived example, but there is really no need for "await" in his "chain()" function:<p><pre><code> function chain () {
(function loop (i) {
if (i > 5) {
// set state to failed
return;
}
check().then((result) => {
if (!result) {
return loop(i + 1);
}
// set state to finished
}).catch((error) => {
// set state to failed
});
}(0));
}
</code></pre>
This is one of my pet peeve with proponents of promises actually. They come up with convoluted examples to argue against callbacks but it's not the callbacks that are a problem, but the person writing the code.<p>Actually, I would argue that promises really made no sense until "await" became available because they introduce extra complexity and (small) performance penalty for no added benefit. Worse, it encourages less experienced developers to write code in a serial manner in situations where this is not necessary (a much bigger performance problem).<p>Even with "await", the only time when it is really useful is when there have to be a several asynchronous operations that must happen serially because they use the result of the previous call. It depends on your field of work, of course, but in my experience these situations are really not that common.<p>Some time ago I wrote an article comparing performance of callbacks vs async/await but it is also an example to show that callback code does not have to be more tedious to write:<p><a href="https://gir.me.uk/posts/node-8-async-await-performance-test.html" rel="nofollow">https://gir.me.uk/posts/node-8-async-await-performance-test....</a>
I know its kind of meta, but what's with all the blog posts lately hosted on a *.christmas domain? These posts seem to have nothing to do with the holiday<p>I'll admit the only reason I've noticed the domain is my corporate IT seems to have all sites on weird TLDs blocked by default :/