我怎样才能顺序执行promises

时间:2018-03-24 15:38:56

标签: javascript node.js callback promise

我有两个需要按顺序执行的事件。当我发送第一个请求时,必须调用event1,当我发送第二个请求时, 必须调用event2。所以我使用了承诺,但也许我不太了解它们是如何工作的...... 我像这样堆叠它们:

let event1 = function(){
 return new Promise1(function(resolve,reject){
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="end1" />
    <endEvent id="end2" />
    <sequenceFlow id="flow1" sourceRef="start" targetRef="decision" />
    <sequenceFlow id="flow2" sourceRef="decision" targetRef="end1">
      <conditionExpression xsi:type="tFormalExpression" 
language="JavaScript"><![CDATA[
      this.variables.input <= 50
      ]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow3" sourceRef="decision" targetRef="end2">
      <conditionExpression xsi:type="tFormalExpression" 
language="JavaScript"><![CDATA[
      this.variables.input > 50
      ]]></conditionExpression>
    </sequenceFlow>
  </process>
</definitions>`;

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

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

function sendEvent(value){
  engine.execute({
  variables: {
    input: value
  }
}, (err, definition) => {
  console.log('Bpmn definition definition started with id', 
definition.getProcesses()[0].context.variables.input);
  console.log('sent event' + value);
  console.log(engine.getState())
});
}

i = 0;
module.exports = (req, res, next) => {
  if(!i++){
    sendEvent(req.body.input);
  }
  console.log(engine.getState())
  next()
}
resolve(/*engine.getState()*/);
});
}

let event2 = function(){
  return new Promise2(function(resolve,reject){

'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;

module.exports = (req, res, next) => {
  if(!i++){
    sendEvent(req.body.rfid);
  }
  console.log(engine.getState())
  next()
}
    resolve(/*engine.getState()*/);
  });
}

event1() 
.then(event2);

问题是只执行第一个事件。在上面的代码中使用promises是否正确?我所理解的是,promises是异步函数的结果,但我的程序需要同步处理。也许我误解了他们,对我的案子有一个更好的解决方案。

1 个答案:

答案 0 :(得分:0)

承诺可以链接。

例如:

function doFirstThing(){
   return new Promise(resolve,reject);
}

doFirstThing()
.then(function(){
  return doSecondThing();
})
.then(complete,error)

顺便说一句,你不需要返回Promise来使用then函数。 then()默认返回promise。