NodeJS在继续之前检查功能是否完成

时间:2013-11-14 20:43:59

标签: javascript node.js asynchronous

我对Node中的异步方法API有疑问。

所以,我有一个函数,我们称之为longSetup(callback)

顾名思义,longSetup(callback)需要很长时间才能完成。但是,此设置可以与其他内容并行完成。所以,在longSetup()发生的同时,我也可以设置其他东西。

因此,一旦longSetup()完成,该类就可以执行另一个函数,例如serveData()

现在,我不知道何时会调用serveData()serveData()基于用户I / O,可以在longSetup()完成之前调用,也可以在longSetup()完成后调用。另外,我从不直接调用serveData()

我确实需要在成功执行longSetup()之前完成serveData(),但我想利用longSetup()可以异步完成的事实,因此我不想实现longSetup()的同步版本;我宁愿在那段时间内完成其他设置。

由于可以随时调用serveData(),因此我想在调用longSetup()时检查serveData()是否已完成。如果完成,请继续serveData()。如果没有,请等待longSetup()完成,然后继续执行。由于longSetup()仅被调用一次,因此在大多数情况下我不会等待。此外,如果用户I / O需要时间,longSetup()也会在第一次调用serveData()时完成。

我已经经历了几个SO问题和答案,关于在执行另一个函数之前等待函数返回/在另一个函数之后触发一个函数等。我理解Node的异步方式以及为什么要使用回调。但是,这是一个不同的用例,我想知道节点是否提供了一些等待另一个异步函数的方法。

全部谢谢!

2 个答案:

答案 0 :(得分:1)

我认为这可能是适合您的解决方案:

var setupInfo = { serveData : false, setupFinished : false }

var longSetup = function() {

    ...

    // at the very bottom
    if (setupInfo.serveData) {
        serveData();
    }
    setupInfo.setupFinished = true }
}

var serveData = function () {
    // at the very top
    if (!setupInfo.setupFinished){
         setupInfo.serveData = true;
         return;
    }

    ... 
}

如果你想多次使用serveData,你必须保留一个计数器而不是简单的bool


不要认为node.js为您的任务提供了一些API,但是肯定有外部库来处理这个问题,它基于promise patternHere是关于此主题的一些相当古老但仍然有用的文章。

答案 1 :(得分:1)

@ arturgrzesiak的回答是从serveData调用longSetup,并且在serveData完成之前无法延迟longSetup的执行。 编辑 在仔细阅读他的回答后,看起来我错了,serveData将在longSetup结束时调用一次。但是我的解决方案应允许多次调用serveData,例如多个用户在设置期间请求数据。

var setupFinished = false;

var longSetup = function() {
    ...
    // at end:
    setupFinished = true;
}

var serveDataWrapper = function(query){
  if(!setupFinished){
    setTimeout(
      function(){
        serveDataWrapper(query);
      },
      200 //ms
    );
  } else { // setup is finished
    serveData(query);
  };
}

var serveData = function (query) {
  // longSetup is now guranteed to be complete
};

app.get('/', function(req, res){
  serveDataWrapper(req.query['query']);
});