Reputation: 854
Inside a vue action, I want to poll my backend (call another async
action like described below? ) until the something has finished processing (frontend shows a loader until progress is over).
In other words, I want to repeatedly make an API call looking like :
actions: {
load: async ({dispatch, commit, state}, {args}) => {
await dispatch('progressPolling', {progressUrl, userId})
// continue ONLY when progress has finished, else blocks at this statement
...
}
progressPolling: async ({dispatch, commit}, {progressUrl, userId}) => {
var finished = false
while(!finished) : {
var progress = await dispatch('getResource', {url: progressUrl, userId: userId})
finished = (progress.data.finished === true)
// timeout of 2 secs
}
}
...
}
My understanding is that that you can use the setTimeout()
statement to wait between calls, but am not sure how to turn this into a non-blocking while statement, or simply what is the best practice to achieve this.
EDIT: "Non-blocking" because I was originally using a wait()
statement in a while
loop. That made the UI freeze each time it had to wait.
Upvotes: 3
Views: 1745
Reputation: 466
I would use recursive function to do this.
progressPolling: async ({dispatch, commit}, {progressUrl, userId}) => {
// Define a recursive function
async function getResource (resolve) {
const progress = await dispatch('getResource', {url: progressUrl, userId: userId})
// Recurse when not finished
if (progress.data.finished !== true) {
setTimeout( () => getResource(resolve), 2000);
}
}
// Kick the recursive function
return new Promise (resolve => getResource(resolve))
// Finished!
}
Upvotes: 2