coder
coder

Reputation: 129

checking progress during promise

I have a very basic question on promise api of javascript. I have one promise call, which may take a while to finish. While it is processing, I want to report progress in the UI - through some percent loading information. then() method just points to the time when the promise api has returned. But how to report progress while it is processing?

I tried looking at some other stackoverflow answers, but mostly they deal with multiple promises, and use setTimeOut() apis. I just have one promise api, and don't know how much time it might take (depends on the data in the database at the time I make the call). Since I do not know the time it might take, I am not sure how to show the percent info as well. Any suggestions?

I am using basic javascript, and knockout observables in the code, and cannot use react or angular (don't have access to it).

Upvotes: 4

Views: 3122

Answers (2)

Jamiec
Jamiec

Reputation: 136239

I have a very basic question on promise api of javascript.

There's a very basic answer; the promise api does not support progress "out of the box".

don't know how much time it might take (depends on the data in the database at the time I make the call).

Without this information, it is impossible to provide any meaningful progress. The first thing you'll need to do is make a quick call to the database to ask "How mch data needs to be loaded". Then, you should load the data in chunks, and provide a means to communicate "chunk X of Y" loaded back to the UI as you are accumulating data. Put simply, this is a basic means of "streaming" data.

And this is why, where you see this done they do it with multiple promises, where each "progress promise" resolves when there is an update to the progress, allowing the UI to update a progress bar.

// fake promise to represent action which should take no more than 90s
var promise = new Promise((resolve) => {
    setTimeout(resolve,20000);
});

// reference to progressbar
var progressBar = document.querySelector('.progress');
var current = 0;

// repeating timer which updates every 5 secs
var updater = setInterval(() => {
   if(current >= 100)
       clearInterval(updater);
   // update by 5/90ths
   var updateAmount = (5/90) * 100;
   current += updateAmount;
   progressBar.style.width = current + "%";
},5000);

// when the long action resolves, set the progress bar to 100 and stop the repeating event
promise.then(() => {
   clearInterval(updater)
   progressBar.style.width = "100%";
   console.log("finished");
});
.progress-bar{
  width:100%;
  height:50px;
}

.progress{
   width:0%;
   height:100%;
   background-color:blue
}
<div class="progress-bar">
  <div class="progress"></div>
</div>

Upvotes: 1

Alexander N. Morgunov
Alexander N. Morgunov

Reputation: 166

You can't show anything in progress if you do not know how many bytes you need to load and how many bytes you already did. The easiest way is showing some loader and that all. Or you just need to split your main promise into a simple and small ones.

Upvotes: 0

Related Questions