Chaining async functions of a module without Promises I know that promises are the current recommended way to go for asynchronous chaining but, every time I use promises, I don't feel as comfortable as I wish. All that "then" statements and managing scopes always look a bit strange for me.
So, this is the way I've been creating modules and chaining functions. I use a simple queue to chain the calls.

In my opinion, the code is more understandable, you don't need "then" statements, you can explicit change context if needed. It looks easier for me.
I would like opinions and improvements suggestions, critics are welcome. Why should I use promise over this?

"use strict";

var pause = function(ms, callback) {
    setTimeout(function() {
        callback();
    }, ms);
};

var temp = {
    prop1: 'This is the temp prop1 property!'
};

var P = function() {
    let queue = [];
    let SCOPE = this;

    this.prop1 = 'Property';

    this.displayProperty = function(property) {
        var me = this;
        queue.push(function() {
            console.log(this[property]);
            me.resolve();
        });
        return this;
    }

    this.setProperty = function(property, data) {
        var me = this;
        queue.push(function() {
            this[property] = data;
            me.resolve();
        });
        return this;
    }

    this.asyncDisplayProperty = function(property, data) {
        var me = this;
        queue.push(function() {
            var scope = this;
            pause(3000, function() {
                console.log(scope[property]);
                me.resolve();
            });
        });
        return this;
    }

    this.resolve = function() {
        let fn = queue.shift();
        if (fn) {
            fn.apply(SCOPE, arguments);
        }
    }

    this.bind = function(s) {
        queue.push(() =&gt; {
            SCOPE = s;
            this.resolve();
        });
        return this;
    }

}

var foo = new P();

foo
    .displayProperty('prop1') //"Property"
    .asyncDisplayProperty('prop1') //"Property" after 3s
    .setProperty('prop1', 'changed property')
    .displayProperty('prop1') //"changed property"
    .bind(temp) //change the context
    .asyncDisplayProperty('prop1') //"This is the temp prop1 property!" after 3s
    .setProperty('prop1', 'changed temp property')
    .displayProperty('prop1') //"changed temp property"
    .resolve();


Just for the record, this is the promise version I've been using:

"use strict";

var temp = {
    prop1: 'This is the temp prop1 property!'
};

var P = function() {
    let CONTEXT = this;

    this.prop1 = 'Property';

    this.displayProperty = function(property) {
        var me = CONTEXT;
        return new Promise((resolve, reject) =&gt; {
            console.log(me[property]);
            resolve();
        });
    }

    this.setProperty = function(property, data) {
        var me = CONTEXT;
        return new Promise((resolve, reject) =&gt; {
            me[property] = data;
            resolve();
        });
    }

    this.asyncDisplayProperty = function(property, data) {
        var me = CONTEXT;
        return new Promise((resolve, reject) =&gt; {
            setTimeout(() =&gt; {
                console.log(me[property]);
                resolve();
            }, 3000)
        });
    }

    this.bind = function(s) {
        return new Promise((resolve, reject) =&gt; {
            CONTEXT = s;
            resolve();
        });
    }
};

var foo = new P();

Promise.resolve()
    .then(() =&gt; foo.asyncDisplayProperty('prop1'))
    .then(() =&gt; foo.asyncDisplayProperty('prop1'))
    .then(() =&gt; foo.setProperty('prop1', 'changed property'))
    .then(() =&gt; foo.displayProperty('prop1'))
    .then(() =&gt; foo.asyncDisplayProperty('prop1'))
    .then(() =&gt; foo.bind(temp))
    .then(() =&gt; foo.displayProperty('prop1'))
    .then(() =&gt; foo.setProperty('prop1', 'changed temp property'))
    .then(() =&gt; foo.displayProperty('prop1'));
You're basically starting to rewriting promises. I think there are pros and cons:

For your solution:


Its a little simpler. I would have created a wrapper function around queue.push to make it clearer and easier to modify. You could also make this into a re-usable base class. Lastly, I'm not sure why you create and refer to me everywhere instead of just referring to SCOPE.
It's your own code so if it doesn't do what you want you can change it.
You don't need to wait/hope someone will implement a feature you need.


For promises:


Promises has more functionality (Promise.all, catch, race) and you can have multiple thens attached to a promise.
Thousand's of people have reviewed the Promise code for bugs.
Other developers will know what promises are but have to learn your code.