Javascript 节点在继续之前检查函数是否完成

Javascript 节点在继续之前检查函数是否完成,javascript,node.js,asynchronous,Javascript,Node.js,Asynchronous,关于Node中的异步方法api,我有一个问题 因此,我有一个函数,让我们调用它longSetup(callback) 顾名思义,longSetup(callback)需要很长时间才能完成。但是,此设置可以与其他操作并行进行。因此,当longSetup()正在进行时,我还可以进行其他设置 因此,一旦longSetup()完成,该类就可以执行另一个函数,例如serveData() 现在,我不知道何时调用serveData()serveData()基于用户I/O,可以在longSetup()完成之前调

关于Node中的异步方法api,我有一个问题

因此,我有一个函数,让我们调用它
longSetup(callback)

顾名思义,
longSetup(callback)
需要很长时间才能完成。但是,此设置可以与其他操作并行进行。因此,当
longSetup()
正在进行时,我还可以进行其他设置

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

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

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

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

我已经回答了一些关于在执行另一个函数之前等待函数返回/一个函数接一个函数启动等的问题,我理解了节点的异步方式以及为什么要使用回调。然而,这是一个不同的用例,我想知道node是否提供了某种方式来等待另一个异步函数


谢谢大家

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

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

    ... 
}
如果您想多次维护数据,您必须保留一个计数器,而不是简单的
bool


不要认为node.js为您的任务提供了一些API,但是肯定有一些外部库来处理这个问题,它们基于
承诺模式

这是一篇关于这个话题的相当古老但仍然有用的文章

@arturgrzesiak的回答是从
longSetup
调用
serveData
,无法延迟执行
serveData
,直到
longSetup
完成edit仔细阅读他的答案后,似乎我弄错了,
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']);
});

从longSetup()的底部调用serveData(),在
longSetup
完成时切换布尔值,并在
serveData
中检查它,然后再开始使用函数的其余部分?您是否查看了承诺?看起来很受欢迎。@dandavis谢谢,但那个用例和我的不同。正如问题所述,我不会直接调用
serveData()
。您可能会在这里遇到一些状态管理。最简单的方法是在启动时将布尔变量
ready
设置为false,
longSetup
的回调可以在触发时将其设置为true。同时,在执行
longSetup
时,使用一种缓冲区/堆栈/数组/任何东西来存储
serveData()
的所有调用。然后回调将清空该缓冲区/堆栈/数组/任何内容,并为其提供服务。感谢您的回复!但是,我不会调用
serveData()
serveData()
将作为某个用户I/O的结果被调用。也就是说,在
serveData()
实现中,我希望等待bool设置完成,然后继续。我可以轮询bool或实现我自己的队列,但我想知道Node是否已经为相同的队列提供了API。更新了代码,使其明确表示我的意思是函数声明。何时以及由谁调用它并不重要,但它仍将提供您所需的同步。是的,如果您坚持在调用
longSetup
的完成回调之前允许调用
serveData
,那么,我所知道的唯一解决方案就是按照@arturgrzesiak在回答中的建议,在全局范围内跟踪变量的状态。我将这个答案标记为正确答案,因为它确实提供了一个解决方案,可以实现我所期望的效果。另外,正如大家所指出的,NodeJS没有为这种效果提供任何本机支持。但是,如果您(@Plato)或其他任何人提出了更新的答案(可能是因为将来会有一个新的API),我也会相应地更新答案。再次感谢!