简体   繁体   English

Node.js异步控制流,其中3个进程处理共享数据

[英]Node.js asynchronous control flow with 3 processes working on shared data

I have node.js app with 3 functions, each one has own interval (or can by fired by another event): 我有3个功能的node.js应用,每个功能都有自己的间隔(或者可以由另一个事件触发):

  • processOrders processOrders
  • clearExpiredOrders clearExpiredOrders
  • clearCancelledOrders clearCancelledOrders

Functions are working on shared data, so only one of them can access this data at the time. 函数正在处理共享数据,因此当时只有其中一个可以访问此数据。

When there is a collision, it should wait until the actual function ends and then run second function immediately, but only once. 发生冲突时,它应该等待直到实际功能结束,然后立即运行第二个功能,但只能运行一次。

For example, if there is processOrders running and clearCancelledOrders is triggered 100 times, it will run clearCancelledOrders only once after processOrders finishes its work. 例如,如果运行processOrdersclearCancelledOrders触发100次,它将运行clearCancelledOrders只有一次processOrders完成其工作之后。

How would you solve this in node.js? 您如何在node.js中解决此问题? Or do you have another idea how to solve this task? 还是您有另一个解决方案?

Here is an example of how to do this very simply with promises: 这是一个如何使用promise非常简单地执行此操作的示例:

var p  = Promise.resolve(); // assuming Bluebird promises or Node 0.11.13+ with Promises.
                            // create a new empty resolved promise.

function doFirst(act){
   return p = p.then(function(){
      return someFirstAction(act); // assumes someFirstAction returns a promise
   })
}
function doSecond(act){
   return p p.then(function(){
      return someSecondAction(act); // assumes someFirstAction returns a promise
   })
}

What this does is queue the operations on the single chain. 这是将单链上的操作排入队列 When it resolves the chain resolves. 解决时,链解决。 It also returns the returned promise, so you can unwrap it and get the value. 它还返回返回的promise,因此您可以将其解包并获取价值。

For example: 例如:

doFirst(1);
doSecond(2);

// some point in the future
doFirst(3).then(function(value){
   // both doFirst(1) and doSecond(2) are done here
   // the value argument is the resolution value of doFirst(3)
});

If you're unsure on how to convert your API to promises - see this question . 如果不确定如何将API转换为Promise,请参阅此问题

Since, you also want to limit the number of times a particular action is run, you can create special methods for it: 由于您还希望限制特定操作的运行次数,因此可以为其创建特殊方法:

doFirst.queued = false;
function doFirst(act){
   if(doFirst.queued) return; // already queued
   doFirst.queued = true;
   return p = p.then(function(){
      return someFirstAction(act).finally(function(){ 
          doFirst.queued = false;
      }); 
   })
}
doSecond.queued = false;
function doSecond(act){
   if(doSecond.queued) return; // already queued
   doSecond.queued = true; 
   return p = p.then(function(){
        return someSecondAction(act); // assumes someFirstAction returns a promise
   }).finally(function(){
        doSecond.queued = false;
   });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM