NodeJS在继续执行之前检查函数是否已完成

4
我有一个关于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()时完成。
我看过几个关于在执行另一个函数/在另一个函数之后触发一个函数等待函数返回的SO问题和答案,并且我理解了Node的异步方式以及为什么要使用回调。但是,这是一个不同的用例,我想知道node是否提供了一种等待另一个异步函数的方法。
谢谢大家!

从longSetup()的底部调用serveData()。 - dandavis
1
longSetup完成时,切换布尔值,并在继续函数的其余部分之前在serveData内部检查它? - thgaskell
你有研究过Promise吗?https://github.com/kriskowal/q 似乎很受欢迎。 - Diver
@dandavis 谢谢,但那个用例与我的不同。正如问题所述,我不直接调用 serveData() - codeBearer
@dandavis 啊,太酷了。这有点像轮询。实际上,我现在正在实现的就是这个,只是想知道他们是否有类似于"asyc_wait"的东西。但还是谢谢!:D 至少我知道我走在正确的方向上。 - codeBearer
显示剩余3条评论
2个回答

2
@arturgrzesiak的回答是从longSetup中调用serveData,并且没有办法延迟执行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']);
});

我将此答案标记为正确,因为它确实提供了实现我所寻求的效果的一个解决方案。同时,正如每个人所指出的,NodeJS本身并没有提供这种效果。但是,如果你(@Plato)或其他人想到了更新的答案(也许由于将来会有新的API),我也会相应地更新答案。再次感谢! - codeBearer

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

    ... 
}

如果您想多次服务数据,则需要保留计数器而不是简单的 bool


不要认为node.js会为您的任务提供一些API,但肯定有外部库来解决这个问题,这些库基于“promise模式”。这里是一篇相当陈旧但仍然有用的关于这个主题的文章。


谢谢您的回复!但是,我不会调用serveData()serveData()将作为某些用户I/O的结果被调用。话虽如此,在serveData()实现中,我希望等待bool直到它被设置,然后再继续执行。我可以轮询bool或实现自己的队列,但我想知道Node是否已经提供了相应的API。 - codeBearer
更新了代码,使其更明确我所指的是函数声明。它将提供你所需的同步,虽然调用时间和调用者并不太重要。 - artur grzesiak
如果您坚持允许在调用longSetup的完成回调之前调用serveData,那么我所知道的唯一解决方案是像@arturgrzesiak在这个答案中建议的那样,在全局范围内跟踪状态。 - Plato

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接