2015-12-16 3 views
0

У меня проблемы с управлением потоком выполнения. Это продолжение для node.js, bluebird, poor control of execution path и node.js table search fails with promises in use. Судя по выводам console.log, моя рекурсивная процедура работает отлично, за исключением того, что первый вызов для решения() (сигнал для n-го рекурсивного вызова) дает зеленый свет следующему коду, который не должен получать этот зеленый свет пока первый вызов рекурсивной подпрограммы вызовет resolve(). Оказывается, первый вызов рекурсивной подпрограммы доставляет ответ, который я хочу сообщить, но к тому времени, когда он сообщает об этом, последующий код больше не слушает его и работает блаженно вместе с «неопределенным» ответом. Плохо.Javascript, узел, обещания и рекурсия

Мой код очень долгий, чтобы поделиться здесь. Я попытался написать небольшую модель проблемы, но не нашел комбинацию факторов для повторения поведения.

Звучит знакомо? Как вы держите надлежащий контроль над обещаниями, выпускающими последующий код вовремя?

Я подумал, что, может быть, первый вызов подпрограммы может запустить массив, переданный в Promise.all, а позже вызовы добавят еще одну запись в этот массив. Я не пробовал. Псих?

+1

Если вы не хотите публиковать кодовую стену здесь, не могли бы вы разместить свой код в скрипке? Очень сложно помочь без кода. – TbWill4321

+0

Действительный пункт, конечно. Опция скрипки невозможна по другим причинам. Сожалею. И спасибо в любом случае. – BaldEagle

ответ

0

Не видя своего фактического кода, мы не можем ответить конкретно.

Звучит знакомо? Как вы должным образом контролируете Promises, выпустив следующий код вовремя?

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

Распространенная ошибка заключается в следующем:

someAsyncOperation().then(someOtherAync()).then(...) 

, которые должны быть:

someAsyncOperation().then(someOtherAync).then(...) 

, где вы должны передать ссылку на следующей функции асинхронной, а не вызывать его немедленно и передавая ее возвращаемое значение.

Я думал, что, может быть, первый вызов подпрограммы может начать массив прошел в Promise.all и последующих вызовах будет добавить еще одну запись в , что массив. Я не пробовал. Псих?

Вы не можете передать массив Promise.all(), а затем добавить вещи в массив позже - это не поддерживается способность Promise.all(). Вы можете связать последующие вещи с результатами Promise.all() или сделать еще Promise.all(), который включает в себя обещание от предыдущих Promise.all() и еще несколько обещаний.

var someArrayOfPromises = [...]; 
var pAll = Promise.all(someArrayOfPromises); 

var someMorePromises = [...] 
someMorePromises.push(pAll); 
Promise.all(someMorePromoises).then(...) 
+0

Вы предложили две модели асинхронного управления. Я использовал ваш предпочтительный. Я чаще использую «someAsync(). Then (function (return, error)» {if (error) ...; return someOtherAsync()}).тогда(...). Хороший момент. – BaldEagle

+0

@BaldEagle - Вы понимаете, что мы не можем точно сказать, что не так с вашим кодом, не видя соответствующую часть кода? Итак, без вашего кода, все, что мы можем сделать, это предложить дикие догадки? – jfriend00

+0

В моей рекурсии всегда задействована одна и та же функция; в цепи нет другого. Назовите его(). Каждое решение() to() выглядит одинаково; Я не знаю о какой-либо способности разрешать() к первому, прежде чем делать resolve() до последнего, чтобы он мог разрешить() до первого ... до первого. Тем не менее, код, который должен зависеть от завершения первого вызова, начинается сразу после первого разрешения(). – BaldEagle