Всем привет!
Ситуация такая: есть массив объектов, есть модуль для nodejs, в котором реализованы только асинхронные версии методов. Нужно в цикле для каждого объекта в массиве выполнить асинхронный метод, но нужно получить результат выполнения метода для предыдущего элемента массива, чтоб решить, необходимо ли продолжать пробегать по элементам массива. В общем задача именно вовремя остановиться в цикле. Загвоздка только в том, что метод асинхронный, и колбек переданный ему дернется неизвестно когда. Цикл уже пробежит до конца и вызовет все для всех. Возможно ли синхронизовать выполнение этого метода??
@Fesor: ASYNC позволяет организовать "лапшу" из колбеков в нормальную логику, при этом проверяя чем закончилась предыдущая асинхронная операция и необходимо ли запускать следующую.
@WebDizi: промисы как по мне универсальнее. В той же Q есть Q.denodify. Если честно я уже давно не видел что бы использовали async.js. Из того что видел больше как раз таки в контексте циклов и больше для "распаралеливания".
Я короче посмотрел на коммент про Async, прочитал как Sync, нашел модуль Sync на гитхабе, все подошло как надо, вызовы блочатся, все как надо, хоть и не воспользовался приведенным модулем, но без этих наводок не вышел бы на то, что было нужно)
@Fesor: Окей, я был неправ, тот модуль работает не так как мне нужно, думаю воспользоваться Q. Застопорился на следующем моменте: делаю Q.nfapply(mythod, params), мне возвращается промис, которому можно сдеать done(function(0{}), и эта функция вызовется когда отработает мой метод. Но делает он это также асинхронно, как и с коллбеками. Как заблочить выполнение скрипта через этот промис, чтоб следующая строчка после моего Q.nfapply() выполнилась строго после выполнения метода, который я туда передаю.
@mmmaaak: а зачем вам это? Ну мол... обычно стараются все сделать асинхронно. Или у вас есть зависимость каждого вызова от результата другого? Просто мне сложно пример придумать.
Но вообще то что вы хотите можно добиться чейнингом. Вот пример бесконечного чейнинга. Если ввести условия для выхода из цикла получится ровно то что вам нужно.
function doWork(args) {
var promise = Q.nfapply(some_func, args);
if (someEndCondition) {
return promise;
}
return promise.done(doWork);
}
doWork(['args']).done(function () {
// вызовется только тогда, когда отработают все те штуки.
}
Если же аргументы вам известны... можно просто сделать так:
Q.all(args.map(function (args) {
return Q.nfapply(some_func, args);
})).done(function () {
// отработает только тогда когда отработают все промисы
});
@Fesor: Есть зависимость вызова метода от результата другого, я в вопросе писал. В методе выполняется достаточно дорогая операция, и нет возможности выполнить для всех элементов массива и потом посмотреть у кого не получилось, нужно делать в цикле пока с одним из элементов получится и прервать цикл.
@mmmaaak: При неудачи произойдет реджект промиса. В обработчике реджекта вы можете вернуть новый промис и продолжить чейнинг. А при успехе обработать успех не добавляя в цепочку новых промисов.