3 ms·
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
by quietbritishjim 7y ago
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.
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.
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);
}
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.
Surely the "manual" function could be implemented with some sort of loop-like
- mywittyname 7y agoI think most JS programmers do something along the lines of... function check() { return new Promise(async (resolve, reject) => { for(let i = 0; i < 6; ++i) { if(await doCheck()) { resolve(true); } } reject(); }); } or... async function check() { for(let i = 0; i < 6; ++i) { const status = await doCheck(); if(status) { return status; } } throw new Exception('failed the 6 checks'); } Though, the same thing could certainly be accomplished with pure promise chains. One could also use the setTimeout method in situations where elapsed time is more important than a fixed number of calls.