为什么JS Promise .then()在resolve()之前评估

时间:2017-02-06 20:17:23

标签: javascript promise

我一直在玩Promise,我把下面的代码放在一起,表现得并不像我期待的那样。你可以在这里用小提琴运行它:

https://fiddle.sencha.com/#view/editor&fiddle/1pmk



function log(txt) {
  var lapsed = new Date().getTime() - START;
  console.log(lapsed, txt);
}
START = new Date().getTime();

var promise = new Promise(function promiseExecutor(resolve, reject) {
  log('in Promise 1 Executor');
  setTimeout(function onSetTimeout() {
    log('in Promise 1 Timeout');
    resolve(123);
  }, 500);
});

var promise2 = new Promise(function promise2Executor(resolve, reject) {
  log('in Promise 2 Executor');
  setTimeout(function onSetTimeout() {
    log('in Promise 2 Timeout');
    resolve(123);
  }, 1000);
});

// sequence
promise
  .then(promise2)
  .then(function onPromiseDone(p) {
    // TODO: why this executes before promise2 resolve?
    log('ALL Promise Done! ' + p);
  });




如果您观看控制台,您会发现"所有承诺已完成"在FIRST承诺解决后立即触发消息,然后半秒后第二个承诺得到解决...

在没有resolve()的情况下触发final(onPromiseDone)怎么可能?

现在,我知道Promise执行程序函数立即开始运行,这不是#34;排序"的好例子。通过将我的承诺包含在" deferred"中,我能够实现正确的行为。功能如下所示:

https://fiddle.sencha.com/#view/editor&fiddle/1pml

尽管如此,这并没有回答我对原始小提琴的问题,我将重复:

在没有resolve()的情况下触发final(onPromiseDone)怎么可能?

谢谢!

1 个答案:

答案 0 :(得分:0)

.then接收两个参数:一个函数在Promise成功解析时触发,一个函数在Promise被拒绝时调用(可以省略)。

在你的例子中,你传递一个新的promisse作为论据。

为了实现你的目标(链),我建议这样的事情:

var promise = new Promise(function (resolve, reject) {
  log('in Promise 1 Executor');
  setTimeout(function onSetTimeout() {
    log('in Promise 1 Timeout');
    resolve(123);
  }, 2000);
});


var callback = function(val) {
  log('received from the first promisse: ' + val)
  return new Promise(function (resolve, reject) {
    log('in Promise 2 Executor');
    setTimeout(function onSetTimeout() {
      log('in Promise 2 Timeout');
      resolve(456);
    }, 2000);
  });
}


// Promise.all([promise, promise2]) // parallelize
// sequence
promise
  .then(callback)
  .then(function(val) {
        log('received from the second promisse: ' + val)
        log('ALL Promise Done! ');
    }
  );

这样,您就可以运行promisse并将callback函数设置为.then参数。因此,就在第一个setTimeout完成时,它会调用resolve并调用callback函数,这将创建一个新的Promise,然后设置新的setTimeout

将输出:

0 "in Promise 1 Executor"
2002 "in Promise 1 Timeout"
2002 "received from the first promisse: 123"
2002 "in Promise 2 Executor"
4002 "in Promise 2 Timeout"
4003 "received from the second promisse: 456"
4003 "ALL Promise Done! "

工作小提琴: https://jsfiddle.net/mrlew/L8b8fow9/

@ Bergi评论后编辑。感谢。