2015-12-27 6 views
2

В моем коде, я использую библиотеку Q в цепи нескольких вызовов API следующим образом:Разрешающая с середины обещание цепи

function long_promise_chain() { 
    var q = Q.defer(); 
    call_api_batch1() 
     .then(function(v) { 
      if (v.bar) { 
       q.resolve(); 
      } else { 
       return call_api_batch_2(); 
      } 
     }) 
     .then(function(v) { 
      if (v.bar) { 
       q.resolve(); 
      } else { 
       return call_api_batch_3(); 
      } 
     }) 
     .then(function(v) { 
      if (v.bar) { 
       q.resolve(); 
      } else { 
       return call_api_batch_3(); 
      } 
     }, function(err) { 
      console.log("err: " + err); 
     }); 
    return q.promise 
} 

Я вижу, что даже если цепь будет решен после того, как первый batch следующий блок then получает прогон и вызывает ошибку - пытается получить доступ к неопределенной переменной, а затем вызывает блок функции (err).

Не могли бы вы предложить правильный путь решения рано.

Обновление: Проблема в том, что если вызывается первый q.resolve(), я не хочу, чтобы следующий. Then в цепочке запускался. В то время как q.resolve вызывается правильно и возвращает управление вызывающему, печатается ошибка, потому что во втором случае нет «v», а ошибка «Не удается прочитать панель свойств неопределенного» при тестировании v. бар.

+0

* «и вызывает ошибку - пытается получить доступ к неопределенной переменной, а затем вызвать функцию (ERR) блок» * Там нет выше код пытается получить доступ к неопределенной переменной. –

+0

Полезно сделать код простым, но в этом случае я боюсь, что вы тоже сделали это * generic. Непонятно, какие последующие функции 'then' предназначены для использования из резолюции предыдущего обещания, которая, как представляется, важна здесь. –

+0

Спасибо за комментарий. Я постараюсь обновить вопрос. – user2738707

ответ

0

В вашем случае есть два отдельных resolve.

  1. Первый нижний регистр q, который содержит отложенный объект. Это обещание, которое вы возвращаете от long_promise_chain.
  2. Во-вторых, обещание на каждом этапе вашей цепи. То есть, обещание возвратилось с каждого звонка then в цепочку до следующего then.

Вы разрешаете или отклоняете q, позвонив по методу на q напрямую. Вы можете разрешить или отклонить обещание then по , возвращая Q.resolve() или Q.reject() от then блок.

Вот пример:

любимый В моем коде, я использую библиотеку Q в цепи нескольких вызовов API следующим образом:

function long_promise_chain() { 
    var q = Q.defer(); 
    call_api_batch1() 
     .then(function(v) { 
      if (condition) { 
       q.resolve(); 
       return Q.reject(); 
      } else { 
       return call_api_batch_2(); 
      } 
     }) 
     .then(function(v) { 
      if (condition) { 
       q.resolve(); 
       return Q.reject(); 
      } else { 
       return call_api_batch_3(); 
      } 
     }) 
     .then(function(v) { 
      if (condition) { 
       q.resolve(); 
       return Q.reject(); 
      } else { 
       return call_api_batch_3(); 
      } 
     }, function(err) { 
      console.log("err: " + err); 
     }); 
    return q.promise 
} 
+0

Эй, спасибо за ответ. Я попытался использовать return Q.resolve() после q.resolve ({}), но последующий .then() в цепочке все равно выполнялся и выдавал ошибку. – user2738707

+0

@ user2738707 Если вы хотите отменить следующий этап, вам нужно использовать Q.reject. Я обновил свой пример кода. –

+0

эй, я пробовал это, но он все еще выполняет другие цепочки после разрешения! – user2738707

1

Я надеюсь, я вас понимаю. Является ли это то, что вы хотите ?:

function long_promise_chain() { 
    var q = Q.defer(); 
    var allDone = false; 
    call_api_batch1() 
     .then(function(v) { 
      if (v.bar) { 
       q.resolve(); 
       allDone = true; 
      } else { 
       return call_api_batch_2(); 
      } 
     }) 
     .then(function(v) { 
      if (!allDone) { 
       if (v.bar) { 
        q.resolve(); 
        allDone = true; 
       } else { 
        return call_api_batch_3(); 
       } 
      } 
     }) 
     .then(function(v) { 
      if (!allDone) { 
       if (v.bar) { 
        q.resolve(); 
        allDone = true; 
       } else { 
        return call_api_batch_3(); 
       } 
      } 
     }, function(err) { 
      console.log("err: " + err); 
     }); 
    return q.promise 
} 
+0

Ну, это работает, и я не должен выполнять другие. Затем блоки после разрешения первого. Then блока. Благодаря! – user2738707