我有这样的功能:
var download = function(url, name) {
http.get(url, function(response) {
// part1 : create a new folder if it doesn't exist
dir = './name';
if (!fs.existsSync(dir)){
fs.mkdirSync(dir);
}
// part 2: download and save file into that folder
response.on('data', function (data) {
fs.appendFileSync(dir, data);
});
})
}
我希望第1部分在第2部分运行之前完成(这样我就可以获得第2部分的目录)。我怎样才能做到这一点 ?
(在上面的代码中,据我所知(我是node.js的新手),两个部分将同时运行,所以我不确定第1部分是否会在第2部分运行之前完成)。
答案 0 :(得分:1)
不,他们不会。两个部分将同时运行
existsSync
和mkdirSync
阻止了来电。因此,只有在执行它们之后才会附加事件处理程序。
但是,我们应该在适用的时候利用异步性。在这种情况下,您可以使用exists
和mkdir
异步对应项。
所以,你的代码可以像这样松散地重构
function download(url, name) {
function attachAppender(filename, response) {
response.on('data', function (data) {
fs.appendFile(filename, function (err) {
res.statusCode = err ? 500 : 200;
response.end();
});
});
}
http.get(url, function (response) {
var dir = './name';
fs.exists(dir, function (exists) {
if (!exists) {
fs.mkdir(dir, function (err) {
if (err) {
res.statusCode = 500;
res.end();
} else {
// pass the actual full file name
attachAppender(filename, response);
}
});
} else {
attachAppender(filename, response);
}
});
});
}
注意: fs.exists
已弃用,可能很快就会删除。更好地使用fs.stat
代替它。
答案 1 :(得分:0)
您正在使用同步功能,因此呼叫会被阻止。但是,正如thefoureye所提到的,出于性能原因,最好使用异步版本。
如果你想避免使用callback hell(即在链接异步调用时你的代码变得越来越难以阅读),你可以使用写在意图中的async.js等库。试图让它更容易编写(当然,更容易阅读)。
以下是从async.js的单元测试中获取的示例:每个async函数都是在另一个之后调用的。
var series = function(test){
var call_order = [];
async.series([
function(callback){
setTimeout(function(){
call_order.push(1);
callback(null, 1);
}, 25);
},
function(callback){
setTimeout(function(){
call_order.push(2);
callback(null, 2);
}, 50);
},
function(callback){
setTimeout(function(){
call_order.push(3);
callback(null, 3,3);
}, 15);
}
],
function(err, results){
test.ok(err === null, err + " passed instead of 'null'");
test.same(results, [1,2,[3,3]]);
test.same(call_order, [1,2,3]);
test.done();
});
}
为了使一系列异步调用更容易读写(例如async / await,fibers.js),还有很多其他举措