我在尝试理解如何在Node.js中使我的代码异步时遇到了麻烦。请参阅下面的代码,分为两种。
好的,这是我的第一次尝试 - 我在这里有三个功能。处理函数(iim),文件复制函数(fse.copy)和归档函数(da)。
我需要在iim之后发生,并且在fse.copy之后发生iim。
第一种方法导致存档发生,但它是空的,因为iim似乎永远不会发生。
da(randomString, function(err) {
if (err) {
log.error(err);
} else {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
}
});
下一个块是另一种方法,它会导致在iim完成之前发生这种情况。
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
});
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
}
});
答案 0 :(得分:2)
以下是我推荐的内容 - 在您的问题中,您说您需要基本上连续运行三个功能 - 对吗?运行功能A,然后运行功能B,最后运行功能C.
最简单的方法是使用asyncjs库。
以下是一个例子:
var async = require('async');
async.series([
function a(cb) {
// do stuff
cb();
},
function b(cb) {
// do stuff
cb();
},
function c(cb) {
// do stuff
cb();
},
], function() {
// this will run once all three functions above have finished
});
现在,让我们说每个函数都需要将数据返回到下一个函数。因此,假设函数B需要从函数A输入才能运行。你是如何实现这一目标的?使用async.waterfall!
var async = require('async');
async.waterfall([
function a(cb) {
// do stuff
cb(null, 'value');
},
function b(val, cb) {
// do stuff with val
cb(null, 'woot');
},
function c(val, cb) {
// do stuff with val
cb(null);
},
], function() {
// this will run once all three functions above have finished
});
不错吧?
希望这有帮助!
编辑:这是一个代码块,显示上面使用asyncjs重构的代码:
async.waterfall([
function(cb) {
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
}
console.log('Finished running fs.copy');
cb(null, sourceImage, randomString);
});
},
function(sourceImage, randomString, cb) {
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running iim');
cb(null, randomString);
});
},
function(randomString, cb) {
da(randomString, function(err) {
if (err) {
log.error(err);
}
console.log('Finished running da');
cb();
});
}
], function() {
console.log('All done!');
});
答案 1 :(得分:1)
所以你可以从第二个例子中将da放入iim的回调中(现在它不是):
fse.copy(temp_path, new_location + file_name, function(err) {
if (err) {
log.error(err);
} else {
log.info("File saved to " + new_location + file_name);
var sourceImage = new_location + file_name;
log.debug(sourceImage);
log.debug(randomString);
iim(sourceImage, randomString, function(err) {
if (err) {
log.error(err);
return;
}
da(randomString, function(err) {
if (err) {
log.error(err);
}
});
});
}
});
也就是说,使用像async(https://github.com/caolan/async)
这样的库可以缩小回调深度