npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

psqueue

v0.0.6

Published

A module to execute a list of promises in order and synchronously

Downloads

5

Readme

PSQueue (Promises Sync Queue)

Gitter dependencies

Getting async ducks in a row.

Have you ever find yourself dealing with this problem: you need to execute async operations (encapsulated in Q promises) in order. The bad thing is that those async operations are dynamically generated and therefore it's not trivial to chain Q promises with then, then, then.

If this is your case, then this module is for you.

How to use it?

  1. Create a PSQueue.
  2. Create your function that returns a Q promise.
  3. Add the function to the queue (indicating the parameters)
  4. Repeat steps 2 and 3 as many times as you want.
  5. Call PSQueue's method resolveAllSync() which will return a Q promise too.

The promise returned by resolveAllSync() will be resolved once ALL the Q promises in the queue are solved. The good part is that the sync queue resolves all the promises in ORDER: ONE AT THE TIME! :)

The resolved value the promise returned by resolveAllSync() will contain an array with the resolved values of all the other synchronously executed promises of the queue.

You can optionally define a torch object and pass it to resolveAllSync function. The object will be systematically passed between the functions in the queue. Functions can then modify the value and pass it to the following functions in the queue. You need to be sure that your function will actually proccess this parameter.

Example:

Q.all resolves all the promises asynchronously. So, in this example:

    var Q = require('q');

    var timestamp = (new Date()).getTime();
    var arr = ['A', 'B', 'C'];

    function doPromiseToItem(item) {
      var deferred = Q.defer();
      var randomFactor = 10000 * Math.random()
      setTimeout(function (rand) {
        console.log(item + ' solved after random ' + (Math.round((rand / 1000) * 100) / 100) + ' secs.');
        deferred.resolve(item);
      }, randomFactor, randomFactor);
      return deferred.promise;
    }

    var promises = [];

    for (var i = 0; i < arr.length; i++) {
      var item = arr[i];
      var promise = doPromiseToItem(item);
      promises.push(promise);
    }

    Q.all(promises).then(function (arrResults) {
      var duration = Math.round(((((new Date()).getTime()) - timestamp) / 1000) * 100) / 100;
      console.log('ALL SOLVED in ' + duration + ' seconds.');
      console.log('Results are:\n' + arrResults.join('\n'));
    });

If you execute it:

    $ cd demos
    $ node QAllTest.js

This is one possible output you might get:

    C solved after random 3.03 secs.
    B solved after random 5.09 secs.
    A solved after random 5.45 secs.
    ALL SOLVED in 5.46 seconds.
    Results are:
    A
    B
    C

As you can see all of the promises ran in parallel (not in a specific order -> C,B,A) and the time it took to complete all of them is nothing but the time it took for the latest one to finish.

PSQueue runs all the promises in order and one at the time: (Example using a torch value)

    var Q = require('q'),
      PSQueue = require('../psqueue'),
      timestamp = (new Date()).getTime(),
      arr = ['A', 'B', 'C'],
      promisesQueue = new PSQueue();

    function doPromiseToItem(item, torch) {
      var deferred = Q.defer();
      var randomFactor = 10000 * Math.random();
      setTimeout(function (rand) {
        console.log(item + ' solved after ' + torch.text + ' taking random ' + (Math.round((rand / 1000) * 100) / 100) + ' secs.');
        torch.text = (torch.text === 'BEGGINING OF TIME' ? item : (torch.text + ',' + item));
        deferred.resolve(item + ':OK');
      }, randomFactor, randomFactor);
      return deferred.promise;
    }

    for (var i = 0; i < arr.length; i++) {
      var item = arr[i];
      promisesQueue.addPromise(doPromiseToItem, item);
    }

    promisesQueue.resolveAllSync({
      text: 'BEGGINING OF TIME'
    }).then(function (arrResults) {
      var duration = Math.round(((((new Date()).getTime()) - timestamp) / 1000) * 100) / 100;
      console.log('ALL SOLVED in ' + duration + ' seconds.');
      console.log('Results are:\n' + arrResults.join('\n'));
    });

If you execute it:

    $ cd demos
    $ node PSQueueTest.js

This is one possible output you might get:

    A solved after BEGGINING OF TIME taking random 9.6 secs.
    B solved after A taking random 5.55 secs.
    C solved after A,B taking random 1.1 secs.
    ALL SOLVED in 16.3 seconds.
    Results are:
    A:OK
    B:OK
    C:OK

As you can see no matter how much time each individual promise took to be solved, all of them are executed in order (A,B,C) and the total time is the sum of the time of each of them. Also you can see how the torch value is modified from function to function appening the name of the item that was previosuly executed. The result of the promises is then returned in an array (arrResults).

What if a promise in the queue fails?

If one promise in the queue fails, then the following promises in the queue are not executed and the rejection value is used for rejecting the queue's promise.

Example:

    var Q = require('q'),
      PSQueue = require('../psqueue'),
      timestamp = (new Date()).getTime(),
      arr = ['A', 'B', 'C', 'D'],
      promisesQueue = new PSQueue();

    function doPromiseToItem(item, torch) {
      var deferred = Q.defer();
      var randomFactor = 10000 * Math.random();
      setTimeout(function (obj) {
        if (obj.item === 'C') {
          console.log(item + ' NOT solved after random ' + (Math.round((obj.rand / 1000) * 100) / 100) + ' secs.');
          deferred.reject(obj.item);
          return;
        }
        console.log(item + ' solved after random ' + (Math.round((obj.rand / 1000) * 100) / 100) + ' secs.');
        torch.push(item);
        deferred.resolve();
      }, randomFactor, {
        "rand": randomFactor,
        "item": item
      });
      return deferred.promise;
    }

    for (var i = 0; i < arr.length; i++) {
      var item = arr[i];
      promisesQueue.addPromise(doPromiseToItem, item);
    }

    var partialResult = [];

    promisesQueue.resolveAllSync(partialResult).fail(function (err, arrResults) {
      var duration = Math.round(((((new Date()).getTime()) - timestamp) / 1000) * 100) / 100;
      console.log('FAILED because I found ' + err + ' after ' + duration + ' seconds.');
      console.log('Partial result is: ' + partialResult.join(','));
    });

If you execute it:

    $ cd demos
    $ node PSQueueTestFail.js

This is one possible output you might get:

    A solved after random 7.35 secs.
    B solved after random 5.06 secs.
    C NOT solved after random 4.76 secs.
    FAILED because I found C after 17.2 seconds.
    Partial result is: A,B

As you can see D was never executed and the torch object has been used to obtain a possible partialResult.

Alias for resolveAllSync

You can use all and allSync as alias of resolveAllSync