【问题标题】:How can I execute promises sequentially如何按顺序执行承诺
【发布时间】:2018-09-03 03:07:07
【问题描述】:

我有两个事件需要按顺序执行。当我发送第一个请求时,必须调用 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);

问题是只执行第一个事件。在上面的代码中使用 Promise 是否符合逻辑?我的理解是,promise 是异步函数的结果,但是我的程序需要同步处理。也许我误解了他们,我的情况有更好的解决方案。

【问题讨论】:

  • 乍一看,您似乎不止一次声明了engine
  • 是的,因为有两个不同的processXml
  • 很难判断它们是否都在一个文件中声明,或者这是来自多个文件的代码放在一起。
  • 这是我整理的多个文件中的代码

标签: javascript node.js callback promise


【解决方案1】:

Promise 可以链接起来。

例如:

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

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

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

【讨论】:

  • 如果我删除了第二个事件中的 return Promise 并更改了 event1 和 event2 之间的顺序,则会显示此类型错误:无法读取属性 'then'。但是,按照您的代码,问题继续存在。 event1 接受我发送的所有请求。可能是下一个呼叫问题?
猜你喜欢
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 1970-01-01
  • 2019-05-30
  • 1970-01-01
  • 2020-06-16
  • 2019-03-08
相关资源
最近更新 更多