2016-10-26 2 views
1

Я пытаюсь работать с async в узле js, чтобы контролировать поток выполнения некоторых функций. В приведенном ниже коде есть три объявленные функции, которые должны печатать соответственно «один», «два» и «три» вместе с выполнением других задач (печать только для того, чтобы я мог видеть, что будет выполняться когда).Async - callback не является функцией

async.waterfall([ 
    function(callback) { 
     settings(); 
     console.log("1"); 
     callback(null, 'one'); 
    }, 
    function(callback) { 
     profile(); 
     console.log("2"); 
     callback(null, 'two'); 
    }, 
    function(callback) { 
     console.log("3"); 
     groups(); 
     callback(null, 'two'); 
    } 
    ]); 

Так что я получаю ошибку «обратный вызов не является функция» в строке обратного вызова (нуль, «два»); Честно говоря, это может быть очень сомнительным вопросом, и я не совсем понимаю, как работает асинхронный водопад. Но я серьезно старался, читая примеры, пытаясь реализовать короткий код и пытаться поиграть с ним.

Интересно, что если async.series используется вместо async.waterfall, такой ошибки нет. Однако async.series будет печатать 1, 2, 3, три, один, два. Цифры внутри модели водопада печатаются последовательно, но функции внутри не выполняются в правильном порядке.

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

+0

Эта проблема возникает, когда вы вставляете вызовы 'async', особенно если вы вызываете' async.series' внутри 'async.waterfall' или наоборот,' ​​async' станет ненадежным. – Sandwich

ответ

2

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

async.waterfall([ 
    function(callback) { 
     callback(null, 'one', 'two'); 
    }, 
    function(arg1, arg2, callback) { 
     // arg1 now equals 'one' and arg2 now equals 'two' 
     callback(null, 'three'); 
    }, 
    function(arg1, callback) { 
     // arg1 now equals 'three' 
     callback(null, 'done'); 
    } 
], function (err, result) { 
    // result now equals 'done' 
}); 

В вашем случае, callback на второй функции будет получили строку one в качестве аргумента. И, следовательно, ошибка, которую вы испытываете.

3

Чтобы упростить это действие, callback(null, 'one') означает, что вы передаете один аргумент для следующего. Значение вашей функции должно принимать 1 параметр перед обратным вызовом.

callback(null, 'one') следует из function(arg1, callback) где arg1 = 'one'

callback(null, 'one', 'two') следует из function(arg1, arg2, callback) где arg1='one' и arg2='two'

async.waterfall([ 
    function(callback) { 
     settings(); 
     console.log("1"); 
     callback(null, 'one'); 
    }, 
    function(arg1, callback) { 
     profile(); 
     console.log("2"); 
     callback(null, 'two'); 
    }, 
    function(arg1, callback) { 
     console.log("3"); 
     groups(); 
     callback(null, 'two'); 
    } 
    ]); 
1

Это неправильный способ использования waterfall попытаться передать другие параметры в функции и поместить последний параметр в качестве обратного вызова.

async.waterfall([ 
function(callback) { 
    settings(); 
    console.log("1"); 
    callback(null, 'one'); 
}, 
function(previous_value,callback) { 
    profile(); 
    console.log("2"); 
    callback(null, 'two'); 
}, 
function(previous_value,callback) { 
    console.log("3"); 
    groups(); 
    callback(null, 'two'); 
} 
], function(err,result){console.log(result)}); 

Вы также забыли передать окончательный обратный вызов после того, как все исполнения.

2

Водопад

Прежде всего, я советую вам использовать Async авто вместо модели водопада причиной этого является в модели водопада мы будем двигаться по одному, как мы сначала закончим выполнение 1-й функции, то перейдите к второму, затем третьему.е мы будем идти в серии какие-либо вопросы не переждать нашу функцию, зависим друг от друга или не

Авто

Преимущества авто в том, что это на самом деле не имеет значения погоды ваши функции зависят друг от друга, как авто могут выполнения задач в серии (для зависимых функций) и параллельно (для функций, которые не зависят друг от друга)

async.auto({ 
    get_data: function(callback) { 
     console.log('in get_data'); 

     callback(null); 
    }, 
    make_folder: function(callback) { 

     callback(null); 
    }, 
    write_file: ['get_data', 'make_folder', function(results, callback) { 

     callback(null); 
    }], 
    email_link: ['write_file', function(results, callback) { 

     callback(null); 
    }] 
}, function(err, results) { 

}); 

здесь, в приведенном выше примере мы имеем функцию get_data и make_folder функции, которые не зависят друг от друга, поэтому мы могут запускать их параллельно и передавая имя get_Data & ma ke_folder мы можем ограничить функцию write_file для запуска только после того, как выполняются обе вышеприведенные функции.

для получения более подробной информации вы можете посетить http://caolan.github.io/async/docs.html#auto

даже взглянуть на async.autoInject она недавно была добавлена ​​ASync вместо авто. но auto будет продолжаться для драгоценных версий async

+0

У меня был один вопрос. Остается ли следующая функция ждать выполнения предыдущей функции? Или мне нужно как-то справиться с этим? –

+0

определенно это @Freya, как в приведенном мною примере I, у нас есть функция write_file, которая будет ждать, когда 'get_data', 'make_folder' будет завершена, когда оба из них будут выполнены, тогда будет выполнен только файл write_file. –

+0

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

Смежные вопросы