2015-02-25 3 views
0

У меня есть три вызова ajax, которые дают мне данные, которые я вдавливаю в массив.jQuery done() три уровня вниз

Второй вызван после первого (в его функции успеха), чтобы массив не заполнился асинхронным.

Моя цель - иметь какой-то звонок в самом конце (отмечен «END !!» в моем коде) с помощью функции jQuery done() (или аналогичной). Однако функция jQuery done() запускается после того, как первый уровень уже достиг своей успешной функции.

var ajaxQuery = $.ormon('ajax', { 
    url: '../getjson', 
    trtyp: 'adm1034', 
    dataType: 'json', 
    data: { 
     clients:1 
    }, 

    success: function(data) { 
     console.log("1"); 

     for (i = 0; i < data.length; i++) { 
      var name = data[i].adr1 + " " + data[i].adr2; 
      kontaktdata.push({name: name, usrid: data[i].usr}); 
     } 

     $.ormon('ajax', { 
      url: '../getjson', 
      trtyp: 'adm1034', 
      dataType: 'json', 
      data: { 
       clients:2 
      }, 

      success: function(data) { 
       console.log("2"); 

       for (i = 0; i < data.length; i++) { 
        var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2; 
        kontaktdata.push({name: name, usrid: data[i].usr}); 
       } 

       $.ormon('ajax', { 
        url: '../getjson', 
        trtyp: 'adm1034', 
        dataType: 'json', 
        data: { 
         clients:3 
        }, 

        success: function(data) { 
         console.log("3"); 
         for(i = 0; i < data.length; i++) { 
          var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2; 
          kontaktdata.push({name: name, usrid: data[i].usr}); 
         } 

         //END!!!!!!!! 

         console.log(kontaktdata); 
        } 
       }); 
      } 
     }); 
    } 
}); 

ajaxQuery.done(function(response) {alert("done");}); 
+0

Не могли бы вы параллельно использовать три вызова ajax? – Bergi

+0

Я не могу, потому что каждый ajax возвращает набор данных. Затем я заполняю это в массив, если я запустил их paralell, массив будет содержать данные из dataset1, а затем dataset2, а затем снова dataset1 (смешение) – DavidDunham

+0

Не обязательно, нет, вы можете запускать их параллельно, а затем объединять все три набора данных в ожидаемом порядке. – Bergi

ответ

0

Вы можете позвонить done() метод на вашем вложенного вызова:

var ajaxQuery = $.ormon('ajax', { 
    url: '../getjson', 
    trtyp: 'adm1034', 
    dataType: 'json', 
    data: { 
     clients: 1 
    }, 
    success: function (data) { 
     console.log("1"); 
     for (i = 0; i < data.length; i++) { 
      var name = data[i].adr1 + " " + data[i].adr2; 
      kontaktdata.push({ 
       name: name, 
       usrid: data[i].usr 
      }); 
     } 

     $.ormon('ajax', { 
      url: '../getjson', 
      trtyp: 'adm1034', 
      dataType: 'json', 
      data: { 
       clients: 2 
      }, 
      success: function (data) { 
       console.log("2"); 
       for (i = 0; i < data.length; i++) { 
        var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2; 
        kontaktdata.push({ 
         name: name, 
         usrid: data[i].usr 
        }); 
       } 

       $.ormon('ajax', { 
        url: '../getjson', 
        trtyp: 'adm1034', 
        dataType: 'json', 
        data: { 
         clients: 3 
        }, 
        success: function (data) { 
         console.log("3"); 
         for (i = 0; i < data.length; i++) { 
          var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2; 
          kontaktdata.push({ 
           name: name, 
           usrid: data[i].usr 
          }); 
         } 

         //END!!!!!!!! 

         console.log(kontaktdata); 
        } 
       }).done(function (response) { 
        alert("done"); 
       }); 
      } 
     }); 
    } 
}); 
0

Что вы могли бы использовать это defered обещание (http://api.jquery.com/deferred.promise):

Что-то, как это должно работать (я не проверял!):

var ajaxQuery = function() { 
    var dfd = new jQuery.Deferred(); 

    $.ormon('ajax', { 
      [...] 

      $.ormon('ajax', { 
        [...] 

        $.ormon('ajax', { 
          [...] 

          success: function(data) { 
            dfd.resolve(data); 
          } 
        }); 
      }); 
    }); 

    return dfd; 
}; 

ajaxQuery().done(function (data) { [...] }); 
+1

Можно, [но не должно] (http://stackoverflow.com/q/23803743/1048572). – Bergi

1

Вместо использования done или т он success callback, вы должны использовать then, который цепей асинхронных действий и дает вам обещание для последнего результата. В вашем случае это будет выглядеть так:

var kontaktdata = []; 
var ajaxQuery = $.ormon('ajax', { 
    url: '../getjson', 
    trtyp: 'adm1034', 
    dataType: 'json', 
    data: {clients: 1} 
}).then(function(data) { 
    console.log("1"); 
    for (var i = 0; i < data.length; i++) { 
     var name = data[i].adr1 + " " + data[i].adr2; 
     kontaktdata.push({name: name, usrid: data[i].usr}); 
    } 
    return $.ormon('ajax', { 
// ^^^^^^ return another promise from the callback 
     url: '../getjson', 
     trtyp: 'adm1034', 
     dataType: 'json', 
     data: {clients: 2} 
    }); 
}).then(function(data) { 
    console.log("2"); 
    for (var i = 0; i < data.length; i++) { 
     var name = "(CRM Lead) - " + data[i].adr1 + " " + data[i].adr2; 
     kontaktdata.push({name: name, usrid: data[i].usr}); 
    } 
    return $.ormon('ajax', { 
     url: '../getjson', 
     trtyp: 'adm1034', 
     dataType: 'json', 
     data: {clients: 3} 
    }); 
}).then(function(data) { 
    console.log("3"); 
    for(var i = 0; i < data.length; i++) { 
     var name = "(MXVV Kunden) - " + data[i].adr1 + " " + data[i].adr2; 
     kontaktdata.push({name: name, usrid: data[i].usr}); 
    } 
    return kontaktdata; //END!!!!!!!! 
}); 

ajaxQuery.done(function(result) { 
    console.log(result); 
    alert("done"); 
}); 

ОК, это хорошо работает, но все еще выглядит утомительно. Что делать, если было сделано не более 3 запросов? Вы хотите, чтобы закодировать это в цикле, который теперь легко можно:

var ajaxQuery = $.when([]); 
for (var client=1; client<=3; client++) (function(client) { 
    ajaxQuery = ajaxQuery.then(function(kontaktdata) { 
     return $.ormon('ajax', { 
      url: '../getjson', 
      trtyp: 'adm1034', 
      dataType: 'json', 
      data: {clients: client} 
     }).then(function(data) { 
      console.log(client); 
      for (var i = 0; i < data.length; i++) { 
       kontaktdata.push({ 
        name: data[i].adr1 + " " + data[i].adr2, 
        usrid: data[i].usr 
       }); 
      return kontaktdata; 
     }); 
    }); 
}(client)); // necessary extra scope for closure 

ajaxQuery.done(function(result) { 
    console.log(result); 
    alert("done"); 
}); 

И с обещаниями, он получает еще лучше - вы можете тривиальным отправить все три запроса параллельно, а затем wait until they're all done и CONCAT результаты:

var requests = []; 
for (var client=1; client<=3; client++) 
    requests.push($.ormon('ajax', { 
     url: '../getjson', 
     trtyp: 'adm1034', 
     dataType: 'json', 
     data: {clients: client} 
    }).then(function(data) { 
     return data.map(function(d) { 
      return {name: d.adr1+" "+d.adr2, usrid: d.usr}; 
     }); 
    })); 
var ajaxQuery = $.when.apply($, requests).then(function() { 
    return [].concat.apply([], arguments); 
}); 
ajaxQuery.then(function(result) { 
    console.log(result); 
    alert("done"); 
}, function(err) { 
    console.error(err + " went wrong"); 
}); 

Использование обещаний имеют дополнительное преимущество, что любой сбой или Аякс асинхронных исключения будут пойманы и вы можете поместить catch -like обработчик в конце концов.

+1

Это гораздо приятнее, чем принятый ответ. Интересно, почему вы конвертировали один из них: var arr = []; для (...) arr.push' в '.map', а другой нет? Кроме того, это очень приятно. –

+0

@BenjaminGruenbaum: Вы имеете в виду массив 'запросов' в последнем фрагменте? Я использовал цикл, потому что я не хотел сопоставлять букву '[1, 2, 3]', а JS по-прежнему не предоставляет функцию «range» :-) – Bergi

Смежные вопросы