Reputation: 41
I have this function which for some reason goes straight from printing 'submit component line after jobstart call' to 'entering while loop':
returned() {
this.numReturned++;
if (this.numReturned !== this.numSubmitting) {
return;
}
console.log('submit component line before jobstart call');
this.submitService.startJobToAuditTable().subscribe();
console.log('submit component line after jobstart call');
let timer = setInterval(() => {
console.log('start of interval');
this.submitService.checkIfJobRunning().subscribe(res => {
console.log("res from job running check is " + res);
this.jobFinished = res;
});
this.submitService.pollAuditTable().subscribe(res => {
console.log("res from audit table:\n\t" + res);
this.auditRows = res;
});
}, 10000); //runs every 10 seconds. will be longer after testing
console.log('entering while loop');
while (this.jobFinished === false) {
}
console.log('clearing interval, job should be finished now');
clearInterval(timer);
return;
}
The console.log and other things inside of the setInterval never get called, and I am confused as to why that would be
Upvotes: 0
Views: 767
Reputation: 14487
Your while loop is consuming execution and blocking everything. If you want to wait until job is done instead of while(done){}
loop you can return a promise:
returned() {
return new Promise((resolve, reject) => {
this.numReturned++;
if (this.numReturned !== this.numSubmitting) {
resolve();
return;
}
console.log('submit component line before jobstart call');
this.submitService.startJobToAuditTable().subscribe();
console.log('submit component line after jobstart call');
let timer = setInterval(() => {
console.log('start of interval');
this.submitService.checkIfJobRunning().subscribe(res => {
console.log("res from job running check is " + res);
this.jobFinished = res;
});
this.submitService.pollAuditTable().subscribe(res => {
console.log("res from audit table:\n\t" + res);
this.auditRows = res;
});
--> if(this.jobFinished === false) {
console.log('clearing interval, job should be finished now');
clearInterval(timer);
resolve();
}
}, 10000); //runs every 10 seconds. will be longer after testing
}
}
resolve()
is used instead of return
, in asynchronous code.
Later, when you call this function, if you want to wait until jobs are finished you can use await
keyword
await returned (); // will wait until resolve() is called
// code after all jobs done
or if async/await is not preferred:
returned().then(() => {
// code after all jobs done
})
Upvotes: 1
Reputation: 51876
Well, if I understand what you're trying to do correctly, you can do something like this:
returned() {
this.numReturned++;
if (this.numReturned !== this.numSubmitting) {
return resolve();
}
console.log('submit component line before jobstart call');
this.submitService.startJobToAuditTable().subscribe();
console.log('submit component line after jobstart call');
let timer = setInterval(() => {
console.log('start of interval');
this.submitService.checkIfJobRunning().subscribe(res => {
console.log("res from job running check is " + res);
this.jobFinished = res;
if (this.jobFinished) {
console.log('clearing interval, job should be finished now');
clearInterval(timer);
}
});
this.submitService.pollAuditTable().subscribe(res => {
console.log("res from audit table:\n\t" + res);
this.auditRows = res;
});
}, 10000); //runs every 10 seconds. will be longer after testing
console.log('entering wait phase');
}
However, it seems you want the function to return when the job is finished, in which case you'll need to return a promise and declare its running scope as async
:
returned() {
return new Promise((resolve) => {
this.numReturned++;
if (this.numReturned !== this.numSubmitting) {
return resolve();
}
console.log('submit component line before jobstart call');
this.submitService.startJobToAuditTable().subscribe();
console.log('submit component line after jobstart call');
let timer = setInterval(() => {
console.log('start of interval');
this.submitService.checkIfJobRunning().subscribe(res => {
console.log("res from job running check is " + res);
this.jobFinished = res;
if (this.jobFinished) {
console.log('clearing interval, job should be finished now');
clearInterval(timer);
resolve();
}
});
this.submitService.pollAuditTable().subscribe(res => {
console.log("res from audit table:\n\t" + res);
this.auditRows = res;
});
}, 10000); //runs every 10 seconds. will be longer after testing
console.log('entering wait phase');
})
}
And then how to call it:
async someOtherMemberMethod() {
await this.returned();
// job is finished here
}
or if you don't want to put it in an async
function:
someOtherMemberMethod() {
this.returned().then(() => {
// job is finished here
});
}
Upvotes: 0
Reputation: 2224
Remove this code, it's blocking, not allowing the process to trigger the next tick. So nothing else, including the setInterval will fire.
// Delete this
while (this.jobFinished === false) { }
Then you can move the clearInterval
this.submitService.checkIfJobRunning().subscribe(res => {
console.log("res from job running check is " + res);
this.jobFinished = res;
if( this.jobFinished !== false ){
clearInterval(timer);
}
});
Upvotes: 0