我如何在 Node 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”上写入,然后我调用请求帖子通过服务器发送数据,仅一次。问题是所有事件都按顺序响应唯一的第一个请求。我希望第一个脚本/事件在第二个事件等待时响应第一个请求,并且在发送第二个请求时,以下脚本执行它,依此类推。有可能吗?
最佳答案
要等待然后做某事,您需要以异步方式运行代码,对此有很多好的方法。
最常见的是 promise,promise 将从异步代码中获取返回值或错误。基本示例(来自 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 .
因此,异步 代码会让您等待一个事件,因为它让您做某事,然后然后对结果做另一件事。
关于javascript - 等待 Node js中的事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49137200/