Twifty Twifty - 1 year ago 83
Javascript Question

How to handle returning a promise when one is already running?

I have a javascript class which currently makes a few asynchronous calls, adds elements to the DOM then calls a user callback. Something like this:

api.load = function() {
if (api.loading || api.loaded)

api.loading = true;
makeAsyncCalls(); // will set api.loaded = true and run all pendingReady

api.ready = function(callback) {
if (!api.loaded) {

This allows me to handle multiple calls to

I'm now trying to update this to make use of javascripts
. The above code would become something like:

api.load = function() {
if (api.loaded) {
// callers attached .then() will still fire
return Promise.resolve(someValue);

if (api.loading) {
// Not sure how to handle this

api.loading = true;
return makeAsyncCalls(); // Which returns a Promise

I don't know how to handle the case where the first Promise has started but not yet completely loaded (resolved in promise speech). The only method I can think of is to return a Promise which wraps a call to
checking the status. Surely there is a better approach. Any suggestions?

To make this clearer. Every call to
must return a
. The first call will initiate the async methods. Further calls need to return a
which can only resolve or reject AFTER the initial
has completed.

Chaining the promises will only work if no values are passed to the success handler (The first
may not return the same value).

Answer Source

A promise itself can be a stand-in for data that is received asynchronously...

api.getAsyncResult = function() {
    if (!api.asyncResult) {
        api.asyncResult = makeAsyncCalls();
    return api.asyncResult;

Any number of callers at any time may now say:

api.getAsyncResult().then(function(result) {
    // use result, which is whatever makeAsyncCalls's promise resolves to

The first call will initiate the async work. Subsequent calls (with the same form) will chain thens to that returned promise. Subsequent to the promise completion, it will continue to deliver it's resolved value as the parameter to the function passed to then()

The makeAsyncCalls() function can maintain the state of a api.loading flag if you need it. There's no need for the api.loaded flag if it's only purpose is to protect against redundant calls (the falsey check in the get function does that).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download