5

I want to have objects request a JavaScript promise, but I don't want them to create separate promises. The logic I want to achieve is as follows - check if a promise is pending, and only if not, create a new promise. Is this possible? According to documenation I can't check status of a promise, I can only handle it after it's fullfilled but I don't want to call handlers for every promise request, and I don't want to run multiple Promises if one Promise's callback can response to all past requests...

The problem I'm trying to solve this way is fetching data from outside server and broadcasting it through event to multiple objects after receiving it.

qiubit
  • 4,708
  • 6
  • 23
  • 37
  • 1
    If you describe in more detail the ACTUAL problem you're trying to solve (including code for your two operations) rather than describing your attempt at your own solution (see the [XY Problem](http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)), we can show you how to use promises appropriately to handle it. – jfriend00 Nov 14 '15 at 00:26
  • 1
    @jfriend00 there are lots of use cases where this pattern applies and is not an XY problem: for example - multiple bits of code perform the same request and you don't want to start a new request for each one but also don't want to cache the values since it might change. – Benjamin Gruenbaum Nov 14 '15 at 00:31
  • @BenjaminGruenbaum - You made a guess as to what the OP wants and you are only able to offer a generic solution to your guess. If the OP provides their actual problem and examples of their actual code, we don't have to guess exactly what they're trying to do and can provide a much, much more specific answer. I am advising the OP on how to make their question a much better question that will invite a much more specific answer and does not involve guessing what they want. You might have guessed right, I'm really not sure. But, any question that requires guessing could be better. – jfriend00 Nov 14 '15 at 00:37
  • 1
    So, do you just want a cache using a promise? So, the first one to request the data creates the actual request and everyone else just uses the same result? – jfriend00 Nov 14 '15 at 00:39
  • Yes, that's exactly what I wanted :) – qiubit Nov 14 '15 at 00:40
  • Do you want the cache to persist so future requests will use the prior result? – jfriend00 Nov 14 '15 at 00:45
  • No, this was really only to prevent unnecessary JSON fetches, but this JSON holds temporary data, so future request (that is not REALLY close to another request) should fetch JSON again. – qiubit Nov 14 '15 at 00:50
  • This sounds like a duplicate of [Caching JavaScript promise results](http://stackoverflow.com/q/31709987/1048572) – Bergi Nov 14 '15 at 14:27

1 Answers1

5

Sure, this is pretty easy to accomplish

var _p = null; // just a cache
function batchRequests(fn){
    if(_p != null) return _p; // if we have an in-flight request, return it
    _p = fn(); // otherwise start a new action
    _p.then(function(){ _p = null; },  // delete cache on resolve
            function(){ _p = null; }); // even on failure
    return _p; // return the new in-flight request
}

Which lets you do:

function delay(){ // just for example, simulate a request
    return new Promise(function(resolve){ setTimeout(resolve, 1000); });
}

var batched = function(){ return batchRequests(delay); };
batched().then(function(){ console.log("All these"); });
batched().then(function(){ console.log("execute after"); });      
batched().then(function(){ console.log("one second, at the same time"); });
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • Can multithreading be an issue? (Sorry if this is a stupid question, I'm new to JavaScript and I'm not sure how these asynchronious functions work, but theoretically we can have multiple threads in batchRequests, they check that there is no promise on the global variable and then each thread makes his own promise...) – qiubit Nov 14 '15 at 00:29
  • 1
    In short - No. In depth - probably not, unless you're running it in Rhino or as an embedded language in another lanugage and inherit multithreading issues from that environment. So "no" applies to most environments (browser, node, etc). – Benjamin Gruenbaum Nov 14 '15 at 00:30
  • @jamesemanon `batchRequests` takes a function as a parameter and returns a function that acts like the input function except it exhibits the behavior OP asked for. A promise represents _a values + time_ and _not_ an action. A promise is like an _already started operation_. If `batchRequests` returned a promise it would be impossible to have the batching-only-until-resolved behavior OP asked for. – Benjamin Gruenbaum Nov 14 '15 at 00:35
  • I dig, but I ran it thru babel, and it errore'd out w/a typeerror. Curious. I'll recheck what I have, perhaps I have it wrong. – james emanon Nov 14 '15 at 00:38