Example of asynchronous queue

by Arnaud Buchholz

HTML

<script src="https://arnaudbuchholz.github.io/blog/jsfiddle-assert.js"></script>

JavaScript

var queue = {

	_stack: [],
  
  _processing: false,
  
  _loop: function () {
    var item = this._stack.shift();
    item
    	.callback()
      .then(item.resolve)
      .then(function () {
      	if (this._stack.length) {
        	this._loop();
        } else {
        	this._processing = false;
        }
      }.bind(this));
  },

  _process: function () {
  	if (this._processing) {
    	return;
    }
    this._processing = true;
    this._loop();
  },
  
  operation: function (callback) {
  	var promise,
    		resolve;
    promise = new Promise(function (resolveHandler) {
    	resolve = resolveHandler;
    });
   	this._stack.push({
      	callback: callback,
        resolve: resolve,
        promise: promise
    });
    this._process();
    return promise;
  },
  
  isCompleted: function () {
  	return Promise.all(this._stack.map(function (item) {
    	return item.promise;
    }));
  }
  
};

queue.isCompleted().then(function () {
	assert(true, "queue is empty");
});

var operation1Completed = false;
queue.operation(function () {
	return Promise.resolve();
}).then(function () {
	operation1Completed = true;
	assert(true, "operation 1 completed");
});

var operation2Completed = false;
queue.operation(function () {
	assert(operation1Completed, "operation 1 is really completed");
	return Promise.resolve();
}).then(function () {
	operation2Completed = true;
	assert(true, "operation 2 completed");
});

queue.isCompleted().then(function () {
	assert(operation1Completed && operation2Completed, "queue is completed");
});