Javascript, узел, обещания и рекурсия

У меня проблемы с управлением потоком выполнения. Это продолжение node.js, bluebird, плохой контроль над путь выполнения и поиск таблицы node.js завершается с ошибкой обещания в использовании. Судя по распечаткам console.log, моя рекурсивная процедура работает отлично, за исключением того, что первый вызов resolve() (сигнал для n-го рекурсивного вызова) дает зеленый свет последующему коду, который не должен получать этот зеленый свет. до тех пор, пока первый вызов рекурсивной подпрограммы не вызовет функцию resolve(). Оказывается, первый вызов рекурсивной подпрограммы дает ответ, который я хочу сообщить, но к тому времени, когда он сообщает об этом, последующий код больше не слушает его и счастливо работает вместе с «неопределенным» ответом. Плохо.

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

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

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


person BaldEagle    schedule 16.12.2015    source источник
comment
Если вы не хотите публиковать кодовую стену здесь, не могли бы вы опубликовать свой код на скрипке? Без кода помочь очень сложно.   -  person TbWill4321    schedule 16.12.2015
comment
Верный момент, конечно. Вариант скрипки невозможен по другим причинам. Извиняюсь. И все равно спасибо.   -  person BaldEagle    schedule 16.12.2015


Ответы (1)


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

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

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

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

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(...)
person jfriend00    schedule 16.12.2015
comment
Вы предложили две модели асинхронного управления. Я использовал ваш предпочтительный. Я чаще использую someAsync().then(function(return, error) {if (error) ...; return someOtherAsync()}).then( ... ). Однако хороший момент. - person BaldEagle; 16.12.2015
comment
@BaldEagle - Вы понимаете, что мы не можем точно сказать вам, что не так с вашим кодом, не видя соответствующей части кода? Итак, без вашего кода все, что мы можем сделать, это предложить дикие предположения? - person jfriend00; 16.12.2015
comment
В моей рекурсии всегда задействована одна и та же функция; другого в цепочке нет. Назовите это (). Каждый метод resolve() для a() выглядит одинаково; Я не знаю о какой-либо возможности разрешить () первый, прежде чем выполнять разрешать () последний, чтобы он мог разрешить () тот, который был до... до первого. Тем не менее, код, который должен зависеть от завершения первого вызова, запускается сразу после выполнения первого вызова resolve(). - person BaldEagle; 16.12.2015
comment
Я полностью понимаю. Я разочарован этим кодом. Я не хочу передавать вам разочарование. Так жаль. - person BaldEagle; 16.12.2015
comment
@BaldEagle - мы можем помочь вам, если вы опубликуете соответствующий код. Мы не сможем вам помочь, если вы не разместите соответствующий код. Это так просто. - person jfriend00; 17.12.2015