问题
I am confused about how to use async.waterfall method to clean up my callbacks. I have a couple functions that are making API calls and returning back results from those API calls via callbacks. I want to pass the results from one api call to the next. I'd also ideally like to enclose these calls in separate functions rather than paste them directly into the async.waterfall control flow (for readability).
I can't quite figure out if you can call a function that has a callback in it, and it will wait for the callback before going to the next function, or not. Also, when the API SDK requires a callback, do I name it to match the callback name in the async.waterfall (in this case called 'callback')?
I may be mixing a lot of things together. Hopefully someone can help me unravel this. Below is a partial code snippet of what I'm trying to do...
async.waterfall([
function(callback){
executeApiCallOne();
callback(null, res);
},
function(resFromCallOne, callback){
executeApiCallTwo(resFromCallOne.id);
callback(null, res);
}],
function (err, res) {
if(err) {
console.log('There was an error: ' + err);
} else {
console.log('All calls finished successfully: ' + res);
}
}
);
//API call one
var executeApiCallOne = function () {
var params = {
"param1" : "some_data",
"param2": "some_data"
};
var apiClient = require('fakeApiLib');
return apiClient.Job.create(params, callback);
// normally I'd have some callback code in here
// and on success in that callback, it would
// call executeApiCallTwo
// but it's getting messy chaining these
};
//API call two
var executeApiCallTwo = function (id) {
var params = {
"param1" : "some_data",
"param2": "some_data",
"id": id
};
var apiClient = require('fakeApiLib');
// do I name the callback 'callback' to match
// in the async.waterfall function?
// or, how do I execute the callback on this call?
return apiClient.Job.list(params, callback);
};
回答1:
If one of your api calls returns successfully, you call the local callback with null
as the first argument. Otherwise, call it with an error, and async.waterfall
is going to stop the execution and run the final callback. For example (didn't test id):
async.waterfall([
function(callback){
executeApiCallOne(callback);
},
function(resFromCallOne, callback){
executeApiCallTwo(resFromCallOne.id, callback);
}],
function (err, res) {
if(err) {
console.log('There was an error: ' + err);
} else {
// res should be "result of second call"
console.log('All calls finished successfully: ' + res);
}
}
);
//API call one
var executeApiCallOne = function (done) {
var params = {
"param1" : "some_data",
"param2": "some_data"
};
var apiClient = require('fakeApiLib');
return apiClient.Job.create(params, function () {
// if ok call done(null, "result of first call");
// otherwise call done("some error")
});
};
//API call two
var executeApiCallTwo = function (id, done) {
var params = {
"param1" : "some_data",
"param2": "some_data",
"id": id
};
var apiClient = require('fakeApiLib');
// do I name the callback 'callback' to match
// in the async.waterfall function?
// or, how do I execute the callback on this call?
return apiClient.Job.list(params, function () {
// if ok call done(null, "result of second call");
// otherwise call done("some error")
});
};
来源:https://stackoverflow.com/questions/29308573/questions-about-async-waterfall-in-node-js