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 compounded 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.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()
}
(I'm using these modules https://www.npmjs.com/package/bpmn-engine https://www.npmjs.com/package/json-server). The server is started writing on the command 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?
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 common 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With