2016-02-04 1 views
0

Если у меня есть два вложенных отложенных объекта, и я жду, чтобы они закончили, как я могу убедиться, что их then заканчивается перед внешними then триггерами?Убедитесь, что внутреннее отложенное завершено перед внешним «затем»

$.when($.ajax({ 
    method: 'PUT', 
    url: someURL, 
    data: { 
     // My data 
    }, 
    callback: function(r) { 

     var deferred1 = $.Deferred(); 
     var deferred2 = $.Deferred(); 

     $.ajax({ 
      method: 'PUT', 
      url: url1, 
      data: { 
       // My data 
      } 
     }).complete(deferred1.resolve); 

     $.ajax({ 
      method: 'PUT', 
      url: url2, 
      data: { 
       // My data 
      } 
     }).complete(deferred2.resolve); 

     $.when(deferred1, deferred2).then(function() { 
      self.parent.container.dialog('close').remove(); 
      self.parent.configurator.container.dialog('close').remove(); 
     }); 
    }, 
})).then(function() { 
    // Some work; e.g. close a loading spinner 
}); 

С выше кодой, сразу же, как deferred1 и deferred2 разрешается, наружная then называется перед тем внутренние then

+0

Вам необходимо остановиться и прочитать учебное пособие, вместо того чтобы продолжать пытаться запутаться вперёд. [Это хороший вариант] (http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/). Ваш код на самом деле не спасен, каждое использование обещаний здесь неверно. – meagar

ответ

2

Обещание не магическое, они не могут просто знать, когда «работу делается ", единственный способ, которым они могут проверить завершение, - до возвращаемое значение. Если вы хотите связать обещания, вы должны должны вернуться с ваших цепей.

В этом примере вы не возвращаетесь после вызова, поэтому он не ждет.

Кроме того - вам не нужно обернуть регулярные обещания с $.when, чем $.when делает конвертировать один или несколько возможно обещает в перспективны для их значений.

$.ajax({ 
    method: 'PUT', 
    url: someURL, 
    data: { 
     // My data 
    }, 
}).then(function(result){ 
    var p1 = $.ajax({ // $.ajax already returns a promise 
     method: 'PUT', 
     url: url1, 
     data: { 
      // My data 
     } 
    }) 
    var p2 = $.ajax({ 
     method: 'PUT', 
     url: url2, 
     data: { 
      // My data 
     } 
    }); 
    return $.when(p1, p2); 
}).then(function() { 
    self.parent.container.dialog('close').remove(); 
    self.parent.configurator.container.dialog('close').remove(); 
}).then(function() { 
    // some action 
}); 
+0

Причина, по которой я явно создал 2 отложенных объекта внутри обратного вызова, заключается в том, чтобы обойти тот факт, что jQuery не имеет своего рода «whenAll». Выполняя это так, как я, я гарантирован, что оба запроса в обратном вызове будут решены до закрытия диалоговых окон. – Thelonias

+1

Вы также гарантированы здесь. '$ .when' является именно функцией" whenAll ". Создав явное отсроченное, вы просто [создавали его явно вместо цепочки] (http://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i- избегай это). –

+0

Предположим, что у меня были успешные обратные вызовы для каждого из p1 и p2, а p1 не удалось завершить p2. Разве это не сразу вызовет первый «то»? Если это так, мне не нужно работать. – Thelonias