Async: разрыв цепи водопада без выдачи ошибки

Созданный на 15 февр. 2011  ·  8Комментарии  ·  Источник: caolan/async

Мне сказали, что мне нужно реорганизовать мой код, использующий асинхронный водопад. Я использовал его в первую очередь потому, что у меня было несколько связанных функций, которые заходили слишком далеко, и я хотел повторно использовать функцию и т.д. хочу передать остальную часть цепочки водопада, потому что это бесполезно - скажем, например, я сделал запрос, и нет результатов, и это не ошибка, я не хочу распространяться полностью вниз без результатов. Если бы я делал это без async, думаю, у меня был бы «последний» обратный вызов, который можно было бы вызвать для выхода из цепочки без явного выброса ошибки. Кажется, что эта функция отсутствует в водопаде. Есть ли способ сделать это чисто? Единственный способ, которым я могу это сделать, - это выдать специальную ошибку, а затем обработать ее в последнем обратном вызове, чтобы вернуть не ошибку.

Самый полезный комментарий

Лично мне нужна такая функциональность, и я считаю, что ее нужно добавить в основную библиотеку.

Вот мой помощник, если кому-то интересно ...

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' и изменяет аргументы, чтобы остальная часть вашего кода не выглядела как ошибка.

Все 8 Комментарий

Привет,

вы, вероятно, уже решили свою проблему, кстати, это мой подход:

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' и изменяет аргументы, чтобы остальная часть вашего кода не выглядела как ошибка.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги