Мне сказали, что мне нужно реорганизовать мой код, использующий асинхронный водопад. Я использовал его в первую очередь потому, что у меня было несколько связанных функций, которые заходили слишком далеко, и я хотел повторно использовать функцию и т.д. хочу передать остальную часть цепочки водопада, потому что это бесполезно - скажем, например, я сделал запрос, и нет результатов, и это не ошибка, я не хочу распространяться полностью вниз без результатов. Если бы я делал это без async, думаю, у меня был бы «последний» обратный вызов, который можно было бы вызвать для выхода из цепочки без явного выброса ошибки. Кажется, что эта функция отсутствует в водопаде. Есть ли способ сделать это чисто? Единственный способ, которым я могу это сделать, - это выдать специальную ошибку, а затем обработать ее в последнем обратном вызове, чтобы вернуть не ошибку.
Привет,
вы, вероятно, уже решили свою проблему, кстати, это мой подход:
var flow = [
async.apply(...),
// ...
];
async.waterfall(flow, function (err) {
if (err === 'ok') return;
// handle error
});
Когда функция вызывает обратный вызов с err = 'ok'
, последний обратный вызов водопада перехватывает его.
У меня аналогичная проблема, и я добавляю оболочку обратного вызова (чего я мог бы избежать), чтобы проверить, является ли это ошибкой для каждого водопада, который я использую. Не так уж чисто, когда водопадов больше одного.
Может ли сама функция обратного вызова иметь другое свойство, называемое 'final', которое люди могли бы вызывать, чтобы перейти к концу.
Что-то типа
function search (cond, callback) {
async.waterfall([function (cb) {
db.get(cond, cb);
},
function (res, cb) {
if (!res || !res.length)
return cb.final();
//do something useful
}
], callback);
}
Мне не нужно оборачивать обратный вызов, и его можно привязать к остальной части программы.
@caolan есть ли что-то, что вам не нравится в запросе на перенос @jnordberg ? И если да, могу ли я что-нибудь сделать, чтобы этот запрос на перенос был принят?
@tax : на самом деле я обнаружил, что мы можем перейти к последней функции, передав 'error' = true следующим образом:
async.waterfall ([функция (обратный вызов) {
обратный вызов (ноль); // <--- перейти к следующему fn
},
function (callback) {
обратный вызов (правда); // <--- перейдем к последнему fn
},
function (callback) {
обратный вызов (ноль); // <--- эта fn не будет вызываться
}
], Перезвони);
@ tot2ivn спасибо за подсказку!
Если вы установите ошибку, результат будет пустым.
var async = require('async');
async.waterfall( [
function( callback ){
console.log('one');
callback( null );
},
function( callback ){
console.log('two');
callback( true, 'more info' );
},
function( callback ){
console.log('three');
callback( null );
}
], function(err, result){
console.log( err, result );
} );
// RESULT
// one
// two
// true undefined
В свете комментария @caolan при закрытии запроса на
Лично мне нужна такая функциональность, и я считаю, что ее нужно добавить в основную библиотеку.
Вот мой помощник, если кому-то интересно ...
exports.breakWaterfall = function(tasks, callback){
async.waterfall(tasks, function(){
if(arguments[0] === 'break'){
arguments[0] = null;
}
callback.apply(null, arguments);
});
}
Если вам нужно перейти к последней функции в задаче, просто вызовите обратный вызов следующим образом: done('break', other, arguments);
.
Помощник просто обнаруживает 'break'
и изменяет аргументы, чтобы остальная часть вашего кода не выглядела как ошибка.
Самый полезный комментарий
Лично мне нужна такая функциональность, и я считаю, что ее нужно добавить в основную библиотеку.
Вот мой помощник, если кому-то интересно ...
Если вам нужно перейти к последней функции в задаче, просто вызовите обратный вызов следующим образом:
done('break', other, arguments);
.Помощник просто обнаруживает
'break'
и изменяет аргументы, чтобы остальная часть вашего кода не выглядела как ошибка.