2013-08-03 1 views
0

Представьте себе, что я три цепочки асинхронных вызовов, как:JQuery Chain & Collect

$.when(first()).then(second()).then(third()) 

first(), second() и third() все возвращенные Отложенный объекты.

В конце цепи я хотел бы собрать все, что было разрешено. На мой взгляд, я полагаю:

$.when(first()).then(second()).then(third()).finally(
    function(first,second,third){ 
    //Do stuff with the three returns here 
    } 
); 

Но есть ли синтаксис для такого поведения? Или как это можно сделать?

Или, иначе говоря, синтаксис, как $.when(first(),second(),third()), который обеспечивает последовательное, не перекрывающиеся выполнение first(), second() и third() будет идеальным.

+0

Что именно вы имеете в виду под «* каждый из них имеет вызов' resolve() 'внутри них *?"? Возвращают ли они обещание? Разрешают ли они какие-либо другие отсрочки? Вы можете показать нам пример кода. – Bergi

ответ

0

Я боюсь, что вы должны прибегнуть к пирамиде гибели (или обратных вызовов):

first().then(function(firstResult) { 
    second(firstResult).then(function(secondResult) { 
     third(secondResult).then(function(thirdResult) { 
      // now you have all three results available in scope 
     }); 
    }); 
}); 

Если вы хотите, чтобы сгладить, что я могу видеть только

var firstResult, secondResult, thirdResult; 
$.when(first()).done(function(r) { firstResult = r; }) 
.then(second).done(function(r) { secondResult = r; }) 
.then(third).done(function(r) { thirdResult = r; }) 
.finally(function() { 
    // use the three results here 
}); 

или какой-то из

first().then(function(r) { return [r]; }) 
.then(function(a) { 
    return second(a[0]).then(function(r) { a.push(r); return a; }); 
}).then(function(a) { 
    return third(a[1]).then(function(r) { a.push(r); return a; }); 
}).finally(function(a) { 
    use a[0], a[1] and a[2] here 
}); 

может быть, помощник функции, с arguments объекта вместо массива, может сим что:

function unfoldLast(fn) { 
    return function() { 
     var args = arguments, 
      l = args.length, 
      last = arguments[l-1]; 
     return fn(last).then(function(r) { 
      var d = $.Deferred(); 
      args[l] = r; 
      d.resolve.apply(d, args); 
      return d; 
     }); 
    }; 
} 
first().then(unfoldLast(second)).then(unfoldLast(third)) 
.done(function(firstResult, secondResult, thirdResult) { 
    // use the arguments! 
}); 
+0

Да, я использую второе решение прямо сейчас. Но, поистине, это надоедает! – Richard

+0

Выполняют ли функции на самом деле полагаться друг на друга? Если нет, вас может заинтересовать функция '' series 'библиотеки async' (https://github.com/caolan/async#series). – Bergi

+0

Нет, они не полагаются друг на друга. Но мне нужно, чтобы они запускались последовательно, не перекрываясь, и результаты были собраны в конце. – Richard