等待节点js中的事件

时间:2018-03-06 17:59:52

标签: javascript node.js events npm bpmn

如何在节点js中等待事件?我正在开发一个bpmn工作流,我必须逐步执行事件。服务器由几个脚本组成,每个脚本都是一个事件,如下所示:

'use strict';
const Bpmn = require('bpmn-engine');
const processXml = `
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 
xmlns:xsi="http://www.w3.org/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()
}

(我正在使用这些模块https://www.npmjs.com/package/bpmn-engine https://www.npmjs.com/package/json-server)。服务器开始在命令行“json-server db.json --middlewares ./script1.js ./script2.js”上写入,然后我通过服务器调用请求post只发送一次数据。问题是所有事件都按顺序回复第一个请求。我希望在第一个请求时第一个脚本/事件回复,而第二个事件正在等待,当第二个请求发送时,以下脚本执行它,依此类推。有可能吗?

1 个答案:

答案 0 :(得分:1)

要等待然后再做一些事情,你需要以异步方式运行代码,有很多好的方法。

最常见的是承诺,承诺将从异步代码获得返回或错误。基本示例(来自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);
});

异步中的“事物”是我们会做某事而然后我们会做点什么,这个然后正在做我们需要的事情而没有在同步代码中。

有很多 npm软件包可以帮助我们做到这一点,例如async-waterfall将运行系列函数,例如来自他们的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
});

它将运行一系列函数的Array.map,避免在我们使用异步代码callback hell时避开好敌人。

所以异步代码会让你等待一个事件,因为它让你做一些事情而然后用结果做另一件事。