最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Wait for event in node js - Stack Overflow

programmeradmin1浏览0评论

How can I wait for an event in node js? I'm developing a bpmn workflow and I have to execute the event step by step.The server is pounded by several scripts and each script is an event, like this:

'use strict';
const Bpmn = require('bpmn-engine');
const processXml = `
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="" 
xmlns:xsi="">
  <process id="theProcess" isExecutable="true">
    <startEvent id="start" />
    <exclusiveGateway id="decision" />
    <endEvent id="RFID_ERRATO" />
    <endEvent id="RFID=M1" />
    <sequenceFlow id="flow1" sourceRef="start" targetRef="decision" />
    <sequenceFlow id="flow2" sourceRef="decision" targetRef="RFID_ERRATO">
      <conditionExpression xsi:type="tFormalExpression" 
language="JavaScript"><![CDATA[
      this.variables.input != "M1"
      ]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="decision" targetRef="RFID=M1">
      <conditionExpression xsi:type="tFormalExpression" 
language="JavaScript"><![CDATA[
      this.variables.input = "M1" 
      ]]></conditionExpression>
    </sequenceFlow>
  </process>
</definitions>`;

const engine = new Bpmn.Engine({
  name: 'exclusive gateway example1',
  source: processXml
});

engine.once('end', (definition) => {
  if (definition.getChildActivityById('RFID_ERRATO').taken) throw new 
Error('<RFID_ERRATO> was not supposed to be taken, check your input');
  console.log('TAKEN RFID=M1', 
definition.getChildActivityById('RFID=M1').taken);
});


function sendEvent(value){
  engine.execute({
  variables: {
    input: value
  }
}, (err, definition) => {
  console.log(engine.getState())
});
}

var i = 0;
//hello.js
module.exports = (req, res, next) => {
  //res.header('X-Hello', 'World')
  //console.log(req);
  if(!i++){
    sendEvent(req.body.rfid);
  }
  console.log(engine.getState())
  next()
}

(I'm using these modules ). The server is started writing on the mand line "json-server db.json --middlewares ./script1.js ./script2.js" and then I call the request post sending the data over the server, only one time. The problem is that all the events reply at the only first request sequentially. I want that the first script/event reply at the first request while the second event is waiting,and when the second request is sent,the following script perform it,and so on. It is possible?

How can I wait for an event in node js? I'm developing a bpmn workflow and I have to execute the event step by step.The server is pounded by several scripts and each script is an event, like this:

'use strict';
const Bpmn = require('bpmn-engine');
const processXml = `
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg/spec/BPMN/20100524/MODEL" 
xmlns:xsi="http://www.w3/2001/XMLSchema-instance">
  <process id="theProcess" isExecutable="true">
    <startEvent id="start" />
    <exclusiveGateway id="decision" />
    <endEvent id="RFID_ERRATO" />
    <endEvent id="RFID=M1" />
    <sequenceFlow id="flow1" sourceRef="start" targetRef="decision" />
    <sequenceFlow id="flow2" sourceRef="decision" targetRef="RFID_ERRATO">
      <conditionExpression xsi:type="tFormalExpression" 
language="JavaScript"><![CDATA[
      this.variables.input != "M1"
      ]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="decision" targetRef="RFID=M1">
      <conditionExpression xsi:type="tFormalExpression" 
language="JavaScript"><![CDATA[
      this.variables.input = "M1" 
      ]]></conditionExpression>
    </sequenceFlow>
  </process>
</definitions>`;

const engine = new Bpmn.Engine({
  name: 'exclusive gateway example1',
  source: processXml
});

engine.once('end', (definition) => {
  if (definition.getChildActivityById('RFID_ERRATO').taken) throw new 
Error('<RFID_ERRATO> was not supposed to be taken, check your input');
  console.log('TAKEN RFID=M1', 
definition.getChildActivityById('RFID=M1').taken);
});


function sendEvent(value){
  engine.execute({
  variables: {
    input: value
  }
}, (err, definition) => {
  console.log(engine.getState())
});
}

var i = 0;
//hello.js
module.exports = (req, res, next) => {
  //res.header('X-Hello', 'World')
  //console.log(req);
  if(!i++){
    sendEvent(req.body.rfid);
  }
  console.log(engine.getState())
  next()
}

(I'm using these modules https://www.npmjs./package/bpmn-engine https://www.npmjs./package/json-server). The server is started writing on the mand line "json-server db.json --middlewares ./script1.js ./script2.js" and then I call the request post sending the data over the server, only one time. The problem is that all the events reply at the only first request sequentially. I want that the first script/event reply at the first request while the second event is waiting,and when the second request is sent,the following script perform it,and so on. It is possible?

Share Improve this question asked Mar 6, 2018 at 17:59 OndesconeOndescone 411 silver badge5 bronze badges 3
  • I'm sure there are a few ways to do this. One that es to mind is stringing promises with .then to make each request only fire after the last has been sent. In a lot of ways this is against the main benefits of the language. Perhaps there is another language you are proficient in such as Python that might be better suited for this? – MindlessRouse Commented Mar 6, 2018 at 18:15
  • Sorry,I'm not proficient in other language.Why is this way against the main benefits of the language? – Ondescone Commented Mar 6, 2018 at 18:53
  • Node uses an single threaded event loop where it sends off things to be done then it is able to work on the next thing. If you ask Node to block each time you send a request out you end up losing out on the benefits of the event loop structure. That being said it can be done. Im not familiar with Bpmn but research Promises. You should be able to create a chain of promises by putting the next call in the .then of the last call to get them to happen in order. GL – MindlessRouse Commented Mar 7, 2018 at 15:36
Add a ment  | 

1 Answer 1

Reset to default 3

To wait and then do something, you need to run the code in an asynchronous way, there's a lot of good approaches for that.

The most mon is the promise, a promise will gets the return or a error from an asynchronous code. Basic example(from Mozilla Developers):

let myFirstPromise = new Promise((resolve, reject) => {
  // We call resolve(...) when what we were doing asynchronously was successful, and reject(...) when it failed.
  // In this example, we use setTimeout(...) to simulate async code. 
  // In reality, you will probably be using something like XHR or an HTML5 API.
  setTimeout(function(){
    resolve("Success!"); // Yay! Everything went well!
  }, 250);
});

myFirstPromise.then((successMessage) => {
  // successMessage is whatever we passed in the resolve(...) function above.
  // It doesn't have to be a string, but if it is only a succeed message, it probably will be.
  console.log("Yay! " + successMessage);
});

The "thing" in asynchronous is that we'll do something and then we'll do something, this then is doing what we need and don't have in a sync code.

There's a lot of npm packages that can help us to do that too, like async-waterfall that will run the functions in series, example from their github:

/* basic - no arguments */
waterfall(myArray.map(function (arrayItem) {
  return function (nextCallback) {
    // same execution for each item, call the next one when done
    doAsyncThingsWith(arrayItem, nextCallback);
}}));

/* with arguments, initializer function, and final callback */
waterfall([function initializer (firstMapFunction) {
    firstMapFunction(null, initialValue);
  }].concat(myArray.map(function (arrayItem) {
    return function (lastItemResult, nextCallback) {
      // same execution for each item in the array
      var itemResult = doThingsWith(arrayItem, lastItemResult);
      // results carried along from each to the next
      nextCallback(null, itemResult);
}})), function (err, finalResult) {
  // final callback
});

It will run an Array.map of functions in series, avoiding a good enemy when we work with async codes, the callback hell.

So async code will let you wait for an event cause it let's you do something and then do another thing with the results.

发布评论

评论列表(0)

  1. 暂无评论