Skip to content

Instantly share code, notes, and snippets.

@mohsin
Created May 14, 2020 19:27
Show Gist options
  • Save mohsin/8a20c76db3efbce7256c98277fe1bbf6 to your computer and use it in GitHub Desktop.
Save mohsin/8a20c76db3efbce7256c98277fe1bbf6 to your computer and use it in GitHub Desktop.
jQueryless Waterfall with custom Deferred
/* Usage
* waterfall(this, [Promise1, Promise2, ...])
* .fail(function(reason){
* console.log('failed')
* })
*/
export function waterfall(...params) {
var steps = [],
dfrd = new Deferred(),
pointer = 0;
params.forEach(function (i, a) {
steps.push(function() {
var args = [].slice.apply(arguments), d;
if (typeof(a) === 'function') {
if (!((d = a.apply(null, args)) && d.promise)) {
d = new Deferred()[d === false ? 'reject' : 'resolve'](d);
}
} else if (a && a.promise) {
d = a;
} else {
d = new Deferred()[a === false ? 'reject' : 'resolve'](a);
}
if(d === undefined) {
dfrd.reject.apply(dfrd, [].slice.apply(arguments));
} else {
d.fail(function() {
dfrd.reject.apply(dfrd, [].slice.apply(arguments));
})
.done(function(data) {
pointer++;
args.push(data);
pointer === steps.length
? dfrd.resolve.apply(dfrd, args)
: steps[pointer].apply(null, args);
});
}
});
})
steps.length ? steps[0]() : dfrd.resolve();
return dfrd;
}
// https://stackoverflow.com/a/18097040/997147
function Deferred(){
this._done = [];
this._fail = [];
}
Deferred.prototype = {
execute: function(list, args){
var i = list.length;
// convert arguments to an array
// so they can be sent to the
// callbacks via the apply method
args = Array.prototype.slice.call(args);
while(i--) list[i].apply(null, args);
},
resolve: function(){
this.execute(this._done, arguments);
},
reject: function(){
this.execute(this._fail, arguments);
},
done: function(callback){
this._done.push(callback);
},
fail: function(callback){
this._fail.push(callback);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment