JSFiddle - React, Tailwind, and code Playground
JavaScript
(function ($) {
"use strict";
var copy = function (a) {
return Array.prototype.slice.call(a);
};
/**
Handle a sequence of methods, stopping on failure by default
@param Array<Function> chain List of methods to execute. Non-deferred return values will be treated as successful deferreds.
@param Boolean continueOnFailure Continue executing even if one of the returned deferreds fails.
@returns Deferred
*/
$.sequence = function (chain, continueOnFailure) {
var handleStep, handleResult,
steps = copy(chain),
def = new $.Deferred(),
defs = [],
results = [];
handleStep = function () {
if (!steps.length) {
def.resolveWith(defs, [ results ]);
return;
}
var step = steps.shift(),
result = step();
handleResult(
$.when(result).always(function () {
defs.push(this);
}).done(function () {
results.push({ resolved: copy(arguments) });
}).fail(function () {
results.push({ rejected: copy(arguments) });
})
);
};
handleResult = continueOnFailure ?
function (result) {
result.always(function () {
handleStep();
});
} :
function (result) {
result.done(handleStep)
.fail(function () {
def.rejectWith(defs, [ results ]);
});
};
handleStep();
return def.promise();
};
}(this.jQuery));
var chain = [
function () {
console.log('step 1');
return (new $.Deferred()).resolve({ step: 1 }).promise();
},
function () {
console.log('step 2');
return (new $.Deferred()).reject({ step: 2 }).promise();
},
function () {
console.log('step 3');
return (new $.Deferred()).resolve({ step: 3 }).promise();
}
];
jQuery.sequence(chain, false)
.done(function () { console.log(this, arguments, 'success'); })
.fail(function () { console.log(this, arguments, 'failure'); });