I have the following code, stripped out of any specifics:
const installation = async() => {
try {
const call = await callToServer();
if('finished' in call) {
return call;
} else {
await callToServer();
}
} catch(e) {
//
}
}
And as you can see, I'd like to recursively call callToServer
until I see finished
inside its response. I understand why my code isn't working and why it's making only 2 calls (or 1, if it sees finished
on the first run), but I don't know how to make it recursive.
I tried with a for
loop and, well, it worked as-is, but in my case, I don't know the number of calls I need to make upfront. So I went to a do...while
loop, since it seemed to fit:
do {
const call = await callToServer();
} while(!('finished' in call));
But this only runs once. It sees that the while(!...
doesn't actually know about call
. How can I make it work?
I have the following code, stripped out of any specifics:
const installation = async() => {
try {
const call = await callToServer();
if('finished' in call) {
return call;
} else {
await callToServer();
}
} catch(e) {
//
}
}
And as you can see, I'd like to recursively call callToServer
until I see finished
inside its response. I understand why my code isn't working and why it's making only 2 calls (or 1, if it sees finished
on the first run), but I don't know how to make it recursive.
I tried with a for
loop and, well, it worked as-is, but in my case, I don't know the number of calls I need to make upfront. So I went to a do...while
loop, since it seemed to fit:
do {
const call = await callToServer();
} while(!('finished' in call));
But this only runs once. It sees that the while(!...
doesn't actually know about call
. How can I make it work?
- 1 Have a global call variable. So you would create const call outside the do-while loop. – P.B.UDAY Commented Dec 29, 2020 at 9:33
-
1
"And as you can see, I'd like to recursively call
callToServer
" - For recursion something has to call itself again. Nothing in your example does this. So something ininstallation
would have to callinstallation
– Andreas Commented Dec 29, 2020 at 9:33 -
Note:
for
is a generic syntax for loops. You don't need to know how many times you need to lop to usefor
. For example you can dofor ( ; condition ; ) ...
which will behave exactly the same aswhile (condition)
– slebetman Commented Dec 29, 2020 at 9:38 -
@slebetman Huh, interesting. Let me see if I can find an "empty
for
" example or some documentation on that. I had always assumed that afor
loop needs to know the number of steps it needs to run for initially. However, iffor ( ; condition ; )
is valid syntax, then it's just personal preference overdo...while
, right? It's just weird to havefor( i=0; !finished; i++)
for this use-case for me. – Vincent Miller Commented Dec 29, 2020 at 9:42 -
C programmers have been using
for (;;) ..
as infinite loop for a long time and it's supported in javascript as well. I've always thoughtfor (;;) ..
is a stupid way to do infinite loop because#define ALWAYS 1; while (ALWAYS) ..
feels more readable to me. But yeah,for
is very flexible – slebetman Commented Dec 29, 2020 at 10:04
4 Answers
Reset to default 6} else {
return await installation();
}
A recursive function would call the entire function again.
You don't necessarily need recursion, a simple loop will work to recall your callToServer
.
You were on the right track with a do...while
loop. You might consider putting a limit in on the number of calls before bombing out. The below will attempt 10 times before doing so - it uses a random chance on whether it works or not so you might see it bombing out.
const installation = async() => {
try {
var call = null;
var i = 0
do {
console.log("attempt",i++)
call = await callToServer();
} while(! ('finished' in call) && i <10 );
return call;
} catch(e) {
//
}
}
const callToServer = async() => {
return new Promise(resolve => {
if(Math.random()>0.95) {
resolve({finished:true})
}
else {
resolve({notfinished:true})
}
})
}
const test = async() => {
var res = await installation()
console.log(res)
}
test()
const installation = async() => {
try {
const call = await callToServer();
if('finished' in call) {
return call;
} else {
return await installation();
}
} catch(e) {
//
}
}
Notice that using async/await is new syntax in ES that is similar to how generators function*
and yield
work, so we can do for, while, recursive call for async function in a sync syntax.
Here is an example that do recursive call while the target value is not met yet
let counter = 0;
let res;
function delay(ms){
return new Promise((res,rej) => setTimeout(res, ms));
}
async function callToServer(){
await delay(100);
return ++counter;
}
async function recursive(){
res = await callToServer();
console.log(`called server with return value = ${res}`);
if(res < 10){
return await recursive();
}
return 'RESULT';
}
(async function main(){
let finalRes = await recursive();
console.log(finalRes);
})()
this code will output:
called server with return value = 1
called server with return value = 2
called server with return value = 3
called server with return value = 4
called server with return value = 5
called server with return value = 6
called server with return value = 7
called server with return value = 8
called server with return value = 9
called server with return value = 10
RESULT
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745046514a4608131.html
评论列表(0条)