javascript - convert function with multiple .get() inside jQuery .each to q promise -
i'm using excellent answer question convert svg images inline html.
the function looks through container or body, finds each .svg
image , converts them inline html.
however, uses $.get()
call retrieve svg files makes function asynchronous.
i'd convert function promise can wait complete before running other things (like adding or removing classes new inline html etc)
my current attempt looks this:
util.convertsvgimages = function(container) { var deferred = q.defer(); container = typeof container !== 'undefined' ? container : $("body"); var getstocomplete = jquery('img.svg', container).length; // total number of $get.() calls complete within $.each() loop var getscompleted = 0; // current number of $get.() calls completed (counted within $get.() callback) jquery('img.svg', container).each(function(index) { var img = jquery(this); var imgid = img.attr('id'); var imgclass = img.attr('class'); var imgurl = img.attr('src'); jquery.get(imgurl, function(data) { getscompleted += 1; var svg = jquery(data).find('svg'); // svg tag, ignore rest if (typeof imgid !== 'undefined') { // add replaced image's id new svg svg = svg.attr('id', imgid); } if (typeof imgclass !== 'undefined') { svg = svg.attr('class', imgclass + ' replaced-svg'); // add replaced image's classes new svg } svg = svg.removeattr('xmlns:a'); // remove invalid xml tags per http://validator.w3.org svg.attr('class', img.attr("data-svg_class") + " svg"); // add class svg object based on image data-svg_class value $('rect', svg).attr("stroke", "").attr("fill", ""); $('line', svg).attr("stroke", "").attr("fill", ""); $('path', svg).attr("stroke", "").attr("fill", ""); $('polyline', svg).attr("stroke", "").attr("fill", ""); $('polygon', svg).attr("stroke", "").attr("fill", ""); $('circle', svg).attr("stroke", "").attr("fill", ""); img.replacewith(svg); // replace image new svg if (getscompleted === getstocomplete){ deferred.resolve('ok'); } }, 'xml'); }); return deferred.promise; };
what best way use promises within asynchronous calls inside $.each()
loop ? using q.all()
?
jqueery.get
returns promise, so, can use that, , jquery.map make array of promises can used in q.all
(or promise.all
matter )
util.convertsvgimages = function(container) { // ... snip var promises = jquery('img.svg', container).map(function(index) { // ... snip return jquery.get(imgurl, function(data) { // ... snip }, 'xml'); }); return q.all(promises); };
usage
util.convertsvgimages().then(.....)
note: if .get fails, q.all reject
as there failure rather resolve
once .gets have finished ... may want use q.allsettled
instead - wait .get
finish (success or fail) , can check failures in .then
code. see documentation q.allsettled
Comments
Post a Comment