0

Basically i have multiple components across the page which own scope and multiple services that fetches some data.

What is best practice for example if one late component which is initiated on some user action needs some conditions from state of other components and some multiple future fetches to be resolved.

For simple example on pseudo language :

   component on click => 
      if( data1.fetched && data2.fetched && component1.action1
          && component2.action2 ...)
      do something ();
      wait for it;

I need to point that there are situation that all of conditions are already resolved and their events emited before component initialized and attached to event listeners and in some situation all this conditions are not even started, in most situation there is combination, so component actino must be aware of past and future.

Currently I am achieving this simply with waiting function like this:

  component on click =>
        wait_for([data1.fetched && data2.fetched && component1.action1 && component2.action2],
                  callback do your staff)

  wait_for(collection,callback) =>
     collection.each => wait(item)
     count = collection.count
     finished = 0;

     wait(item) =>
        if(item) 
          respond(item)
        else
          setTimeout => wait(item), 1000

     respond(item)
       finished++
       if(count == finished)
          callback do your staff

Basically i can not do event listeners because some components are as i said initialized long after those emits fired but i dont know about Promises, what about them dealing with things that are already settled in past like done fetches and state changes.

In real use example lets say that we have component google map that is inserted on user action long after one of its dependency google maps library initialized for other component, but this one needs another dependency, for example google places api to fetch an also needs to wait for state parameter from component address field to emit some action ( but component for other reasons need to be initialized before that action )

Basically question is what is best practice for multiple async condition to be awaited to continue to some action on javascript and are there some library especially for this ( no jQuery, just library for this, like axios )

Dejan Milosevic
  • 313
  • 4
  • 14

2 Answers2

0

You're basically describing the perfect use case for promises. Yes, promises will still be usable indefinitely, even after they have resolved/rejected, as long as you still have a reference to them. For example:

let pr1 = new Promise((resolve, reject) => {
  console.log("I'm about to resolve right now");
  resolve('hello world');
});

setTimeout(()=> {
  pr1.then(x=> console.log(x));
}, 5000);

pr1 has resolved almost immediately, and 5 seconds later when the setTimeout triggers, the .then is still able to make use of the return value of the already-resolved Promise.

Of course if the Promise hasn't resolved yet (say if we had a process in pr1 which took 10 seconds), the .then would just wait until the Promise resolved before it would run.

David784
  • 7,031
  • 2
  • 22
  • 29
  • It might also be worth mentioning as an afterthought that you can usually use a Promise multiple times (not chaining, but having multiple `.then`s all depending on the same Promise, and they generally will all have access to the return value. There are however a few edge-cases where parts of a return value of a promise might be usable only once, e.g. `fetch`. Once you've done `resp.text()`, you couldn't do a `resp.json()`. (But in that instance you could do a `resp.clone().text()` and then still be able to do a `resp.json()` too) – David784 Jul 10 '18 at 00:16
0

It is a good question. Given the emphasis is on asynchronous programming, it's more challenging but JS is just full of surprises and a powerful language anyway! I feel, you will need a combination of singletons and promises to resolve the above problem. singletons to keep the state of actions like component1.action1 and promises obviously for async execution.

An example of invoking a singleton pattern can be as follows (If you know angularJS, think of it like factory or service :

var myInstance = (function() {
  var privateVar = '';

  function privateMethod () {
    // ...
  }

  return { // public interface
    publicMethod1: function () {
      // all private members are accesible here
    },
    publicMethod2: function () {
    }
  };
})();

As far as Async libraries, there is no single 'right way' ever. i'm listing my favourites FYR:

  1. async.js: Async.parallel() is useful when we need to coordinate a series of async operations which can be executed independently of each other and for which we want to take some action when all the tasks have successfully completed.

  2. Bluebird.js is another well written library for async operations. Follow the cheat sheet here -https://devhints.io/bluebird

Pruthvi Kumar
  • 868
  • 1
  • 7
  • 15