如何使一些同步代码在其他asynchronous代码之前运行?

我有这样的function:

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运行之前总是完成)。

两部分将同时运行

不,他们不会。 existsSyncmkdirSync阻止调用。 所以,只有在它们被执行后,事件处理程序才会被附加。

但是,只要适用,我们应该利用这种asynchronous性。 在这种情况下,您可以使用existsmkdirasynchronous对应。

所以,你的代码可以像这样松散地重构

 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而不是它。

您正在使用同步function,以便阻止呼叫。 但是,正如漏油提到的,出于性能原因,最好使用asynchronous版本。

如果你想避免callback地狱 (即你的代码变得越来越难以阅读,因为你链接asynchronous调用),你可以使用一个库,如async.js写的目的是为了更容易写(当然,更容易阅读)。

下面是从async.js的unit testing中取得的一个例子:每个asynchronous函数都在另一个之后被调用。

 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(); }); } 

为了使一系列的asynchronous调用更容易读写,还有很多其他的举措(比如async / await,fibers.js)