Node.js / Promises调用序列

时间:2018-02-25 13:54:15

标签: javascript node.js promise

我有以下node.js代码:

var params = initDbParams();
query().then(orders => function(){
  return match(orders);
}).then(() => function(){
  return place();
}).catch(err => {
  console.log("Error");
});


function initDbParams() {
  console.log("initDbParams Start");
  var a = 1;
  var b = 2;
  var c = 3;
  console.log("initDbParams End");
  return a+b+c;
}

function update() {
  return new Promise(function(resolve, reject ){
    console.log("update Start");
    setTimeout(function(){
        console.log("update timeout over");
    }, 1000);
    console.log("update End");
    resolve();
  });
}

function del() {
  return new Promise(function(resolve, reject ){
    console.log("delete Start");
    setTimeout(function(){
        console.log("del timeout over");
    }, 1200);
    console.log("delete End");
    resolve();
  });
}

function place() {
  return new Promise(function(resolve, reject ){
    console.log("place Start");
    setTimeout(function(){
        console.log("place timeout over");
    }, 1500);
    console.log("place End");
    resolve();
  });
}

function write() {
  return new Promise(function(resolve, reject ){
    console.log("write Start");
    setTimeout(function(){
        console.log("write timeout over");
    }, 2000);
    console.log("write End");
    resolve();
  });
}

function query() {
  return new Promise(function(resolve, reject ){
    console.log("query Start");
    setTimeout(function(){
        console.log("query timeout over");
    }, 3000);
    var orders = [12,24,25,100];
    console.log("query End");
    resolve(orders);
  });
}

function match(orders) {
  return new Promise(function(resolve, reject ){
    console.log("match Start");
    while(orders.length !== 0)
    {
      var order = orders.shift();
      del().then(() => {
        write();
      })
    }
    console.log("match End");
    resolve();
  });
}

我得到以下输出:

  1. initDbParams开始
  2. initDbParams结束
  3. 查询开始
  4. 查询结束
  5. 我希望得到以下结果:

    1. initDbParams开始
    2. initDbParams结束
    3. 查询开始
    4. 查询超时
    5. 查询结束
    6. 匹配开始
      1. del Start
      2. del End
      3. 写开始
      4. 写完
    7. 匹配结束
    8. 我需要更改什么才能获得预期效果? 感谢您的支持!

1 个答案:

答案 0 :(得分:0)

setTimeout仍然是异步的,在promise中调用并不会改变它。您的所有timeout over日志将在稍后发生,而代码会立即继续记录end并解决承诺。你需要在异步回调中调用resolve!同样的事情在match中,你也应该避免使用Promise constructor antipattern

它应该是这样的:

function delay(t) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      console.log("timeout over");
      resolve(); // in here!
    }, t);
  });
}

然后,您可以重复使用该功能,以避免重复自己:

function update() {
  console.log("update Start");
  return delay(1000).then(function(){
    console.log("update End");
  });
}

function del() {
  console.log("delete Start");
  return delay(1200).then(function() {
    console.log("delete End");
  });
}

function place() {
  console.log("place Start");
  return delay(1500).then(function() {
    console.log("place End");
  });
}

function write() {
  console.log("write Start");
  return delay(2000).then(function() {
    console.log("write End");
  });
}

function query() {
  console.log("query Start");
  return delay(3000).then(function() {
    var orders = [12,24,25,100];
    console.log("query End");
    return orders;
  });
}

function match(orders) {
  console.log("match Start");
  var promises = orders.map(function(order) {
    return del().then(write);
  });
  return Promise.all(promises).then(function() {
    console.log("match End");
  });
}

此外,.then(orders => function(){ … })没有意义。它应该是

query().then(function(orders) {
  return match(orders);
}).then(function() {
  return place();
}).catch(err => {
  console.log("Error");
});

query().then(orders => 
  match(orders)
).then(() =>
  place()
).catch(err => {
  console.log("Error");
});

但不是箭头函数和函数表达式。