0

I need to do some async ajax calls and in the end of every single one I push a number to an array when all ajax calls finished I call my callback function with this array. But can't figure out how to do so..

So I've tried to implement the deferred method in my code like shown here

Ended up like this:

function uploader(uploads, cb) {
  var def     = [];
  var reslist = [];
  $.each(uploads,function(key,value){
    if(!value.sync){
      def.push(_upload(value));
    }
  });
  function _upload(upload){
    var dfd = $.Deferred();
    getAntrag(upload.timestamp, function(json) {
      $.ajax({
        url: 'http://api.***.com/',
        type: "POST",
        data: {
          customer: json
        },
        async: false,
        success: function(msg) {
          try {
            var res = JSON.parse(msg);
          } catch (err) {
            dfd.reject();
          }

          if (res.mldgcode === '0000') {
            reslist.push(res.data.ident);
            dfd.resolve();

          } else {
            dfd.reject();
          }

        }
      });
    });
    return dfd.promise();
  }
  $.when.apply($,def).done(function(){
    console.log('all done');
    cb(reslist);
  });
  $.when.apply($,def).fail(function(args){
    console.log('failargs',args);
    cb(args);
  });
}

So but now the done handler is called before my dfd.resolve().

What do I miss here ?

Community
  • 1
  • 1
Marvin Oßwald
  • 376
  • 1
  • 3
  • 20
  • Try `$.when(def).done` – Regent Aug 22 '14 at 11:34
  • How do you know when `dfd.resolve()` executes, did you put a log there? – Bergi Aug 22 '14 at 12:53
  • 2
    Why do you use `async:false`??? – Bergi Aug 22 '14 at 12:54
  • @Bergi yes I did, and the async:false doesn't matter in my opinion but I tested it without it - no change – Marvin Oßwald Aug 22 '14 at 13:49
  • Hm, this is really odd, looks like it should be working. Can you log the value of `def` right before you call `$.when`? – Bergi Aug 22 '14 at 13:51
  • @Bergi oh man thank you very much the `async:false` was the problem.. I'm such an idiot I lost overview of my code :D if you post it as answer it would be a pleasure to mark it as accepted ;) – Marvin Oßwald Aug 22 '14 at 13:55
  • `getAntrag` is asynchronous, isn't it? I wonder how it made a difference then. And the `done` handler must not be called before `resolve()` when all promises are correctly constructed and passed to `when`. – Bergi Aug 22 '14 at 14:14
  • Marvin, for a slightly cleaner solution, (a) use `$.map(uploads, ...)`to build `def`, (b) return null if `value.sync` is thuthy, (c) resolve the Deferreds with `dfd.resolve(res.data.ident)` and allow the promises to convey the data rather than build the separate array `relist`, (d) in the done handler, compose what was `relist` with `Array.prototype.slice.apply(arguments)`. Also take a look at the fail hanlder; I don't think that what you call `args` is plural, ie not the array that `cb()` appears to expect. – Roamer-1888 Aug 22 '14 at 16:55
  • I'll post my suggestions in full if you wish but would need to do so as an answer (which they are not). – Roamer-1888 Aug 22 '14 at 16:57
  • Testing in Opera, `async:false` makes no difference - [demo](http://jsfiddle.net/ecy1jszz/), but maybe some other browsers don't fire the success handler. – Roamer-1888 Aug 25 '14 at 07:47

0 Answers0