javascript - How to make sure $.each pushes all deferreds in jQuery? -


i have following jquery code:

    myfunc: function(cmd, obj){          var idtoextmap = this. map;         var requireres = this.reqinst;         var deferreds = [];         var ret = true;         $.each(idtoextmap[cmd], function(key, ext){                 if(ext.$classins && ext.$classins.prepare) {                     var returnedvalue = ext.$classins.prepare(obj);                     deferreds.push(returnedvalue);                     $.when(returnedvalue).done(function(satisfied){                         if(ret!==false){                             ret = satisfied;                         }                     });                 } else {                     requireres(ext).done(function(){                         var cls = $.tofunction(ext.$jscls);                         if(cls) {                             ext.$classins = new cls();                             if(ext.$classins.prepare){                                 var returnedvalue = ext.$classins.prepare(obj);                                 deferreds.push(returnedvalue);                                 $.when(returnedvalue).done(function(satisfied){                                     if(ret!==false){                                         ret = satisfied;                                     }                                 });                             }                         }                     });                      }                });              $.when.apply(null, deferreds).done(function(){                 return ret;             });         } 

the problem having $.when.apply executed before deferreds pushed deferreds array. how can make sure $.when.apply executed once deferreds pushed deferreds array?

the main thing have ensure promises pushed onto array synchronously. deferreds.push(...) burried inside done callback, push() asynchronous , array guaranteed still empty when $.when.apply(...) executed.

some other issues can fixed :

  • code repetition around ext.$classins.prepare(obj) can avoided rearrangement.
  • the cumbersome outer var ret can avoided exploiting promise rejection.

with other minor tidying, ended (untested) :

myfunc: function(cmd, obj) {     var requireres = this.reqinst;     var promises = $.map(this.map[cmd], function(key, ext) {         var p; // p promise         if(ext.$classins) {             p = $.when(ext.$classins);         } else {             p = requireres(ext).then(function() {                 var cls = $.tofunction(ext.$jscls);                 if(cls) {                     ext.$classins = new cls();                 }                 return ext.$classins || null;             });         }          /* @ point, `p` promise resolved either created `cls()` object or freshly created 1 */          // inside `$.map(...)`, `return p.then(...)` causes promise delivered `p.then(...)` pushed onto `promises` array.         return p.then(function($classins) {             if($classins && $classins.prepare) {                 return $classins.prepare(obj).then(function(satisfied) {                     if(!satisfied) {                         // here, returning rejected promise equivalent setting original `ret` irrevocably `false`.                         return $.deferred().reject(new error(".prepare() not satisfied"));                     }                 });             } else {                 // may want reject if `$classins` or `$classins.prepare` doesn't exist.                 // if not, delete else{} clause.                 return $.deferred().reject(new error(".prepare() not called"));             }         });     });      /* @ point, `promises` array of promises - or resolved, or pending */      // here, instead of boolean `ret`, can exploit joined promise's success/error paths :     // * success path equivalent ret == true.     // * error path equivalent ret == false, or unpredicted error.     return $.when.apply(null, promises).then(function() {         // success.         // whatever necessary here or in `myfunc().then(function() {...})`.     }, function(e) {         // error occurred.         // whatever necessary here or in `myfunc().then(null, function() {...})`.         console.error(e); //for example     }); } 

comments should explain what's going on.


Comments

Popular posts from this blog

jquery - How do you format the date used in the popover widget title of FullCalendar? -

asp.net mvc - SSO between MVCForum and Umbraco7 -

Python Tkinter keyboard using bind -