如何在其他一些异步代码之前制作一些同步代码 运行?

How to make some synchronous code run before some other asynchronous code?

我有这样的函数:

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 部分之前 运行s).

both parts will run simultaneously

不,他们不会。 existsSyncmkdirSync 是阻塞调用。因此,只有在它们执行后,事件处理程序才会被附加。

但是,我们应该在适用的时候利用异步性。在这种情况下,您可以使用 existsmkdir 异步对应项。

因此,您的代码可以像这样松散地重构

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

您正在使用同步功能,因此调用被阻塞。但是,正如 thefoureye 提到的那样,出于性能原因,最好使用异步版本。

如果你想避免写callback hell (i.e your code becomes more and more difficult to read as you chain asynchronous calls), you can use a library such as async.js 的意图是试图让它更容易写(当然也更容易阅读)。

这里是取自 async.js 的单元测试的示例:每个异步函数都在另一个之后调用。

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)