$.fn.deferQueue = function(callable, options){
options = Object(options);
var it = (this.get() || [])[Symbol.iterator]();
var stop = false, cond = null;
var self = this;
this.stop = function(){ stop=true; };
this.end = function(_cond){ cond = _cond };
var tid = 0;
var iterate = function(){
if(tid) clearTimeout(tid);
var o = it.next();
if(cond instanceof Function && cond(o.value)) return;
if(o.done || stop) return;
var d = callable.call(self, o.value);
if(options.timeout) tid = setTimeout(function(){ d.reject('timeout'); }, options.timeout);
if(options.success) d.done(options.success);
if(options.fail) d.fail(options.fail);
d[options.iterate || 'always'](iterate);
}
iterate();
return this;
}
function log(text){
console.log('Log: '+text);
}
function error(text){
console.log('Error: '+text);
}
let q = [
function (D) { setTimeout(function () { console.log("a - " + Date.now()); D.resolve('function 1'); }, 5000); },
function (D) { setTimeout(function () { console.log("b - " + Date.now()); D.resolve('function 2') }, 2500); },
function (D) { setTimeout(function () { console.log("c - " + Date.now()); D.resolve('function 3') }, 0); },
'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png',
'https://unreachabe_domain/image.png',
'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_150x54dp.png',
null,
'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'
];
$(function(){
var
display_timeout = parseInt($('#container').data('display-timeout')),
loading_timeout = parseInt($('#container').data('loading-timeout'));
$(q).deferQueue(function(e){
var D = $.Deferred();
if(typeof(e) == 'string') $('<img/>').attr('src',e).on('load',function(){ setTimeout(function(){ D.resolve(e); },display_timeout)})
.on('error', function(){ D.reject(e) })
.appendTo('#container');
else if(e instanceof Function) e(D);
D.done(log).fail(error);
return D;
},{iterate:'always',timeout:loading_timeout}).end(function(e){ return e===null; });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre>
usage : $(<iterable>).deferQueue(<function(element)>,<options>)
options:
timeout: int(seconds)
iterate: string(always | done | fail)
success: function
fail: function
</pre>
<div id="container" data-display-timeout="1000" data-loading-timeout="3000">
</div>