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(() => {
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) => {
console.log(me[property]);
resolve();
});
}
this.setProperty = function(property, data) {
var me = CONTEXT;
return new Promise((resolve, reject) => {
me[property] = data;
resolve();
});
}
this.asyncDisplayProperty = function(property, data) {
var me = CONTEXT;
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(me[property]);
resolve();
}, 3000)
});
}
this.bind = function(s) {
return new Promise((resolve, reject) => {
CONTEXT = s;
resolve();
});
}
};
var foo = new P();
Promise.resolve()
.then(() => foo.asyncDisplayProperty('prop1'))
.then(() => foo.asyncDisplayProperty('prop1'))
.then(() => foo.setProperty('prop1', 'changed property'))
.then(() => foo.displayProperty('prop1'))
.then(() => foo.asyncDisplayProperty('prop1'))
.then(() => foo.bind(temp))
.then(() => foo.displayProperty('prop1'))
.then(() => foo.setProperty('prop1', 'changed temp property'))
.then(() => foo.displayProperty('prop1'));