javascript - ES6 promise execution order - Stack Overflow

I would expect the output for the following snippet to be 1, 2, 3, 4.But, the actual output order is

I would expect the output for the following snippet to be 1, 2, 3, 4. But, the actual output order is 1, 4, 3, 2.

self.promiseChain = new Promise(function (resolve, reject) {
  setTimeout(resolve, 4000);
}).then(function () {
  console.log(1);
});

self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 3000);
  }).then(function () {
    console.log(2);
  });
});

self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 2000);
  }).then(function () {
    console.log(3);
  });
});
self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 200);
  }).then(function () {
    console.log(4);
  });
});

/

Everything I've read about promises indicates it should be possible to get the desired order in a 'flat' chain like this. Apparently I'm missing some detail? Could someone help point me in the right direction?

Here's a fiddle (/) for how to do it in a non-flat way, but it's harder to reason about and makes sequential chaining awkward.

I've searched similar issues on stack overflow but none of them answer the question generically using a straightforward example (that I could find).

I would expect the output for the following snippet to be 1, 2, 3, 4. But, the actual output order is 1, 4, 3, 2.

self.promiseChain = new Promise(function (resolve, reject) {
  setTimeout(resolve, 4000);
}).then(function () {
  console.log(1);
});

self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 3000);
  }).then(function () {
    console.log(2);
  });
});

self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 2000);
  }).then(function () {
    console.log(3);
  });
});
self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 200);
  }).then(function () {
    console.log(4);
  });
});

http://www.es6fiddle/imu5bhoj/

Everything I've read about promises indicates it should be possible to get the desired order in a 'flat' chain like this. Apparently I'm missing some detail? Could someone help point me in the right direction?

Here's a fiddle (http://www.es6fiddle/imu6vh1o/) for how to do it in a non-flat way, but it's harder to reason about and makes sequential chaining awkward.

I've searched similar issues on stack overflow but none of them answer the question generically using a straightforward example (that I could find).

Share Improve this question asked Apr 10, 2016 at 6:31 l pl p 5281 gold badge7 silver badges18 bronze badges 2
  • 1 Did you mean self.promiseChain = self.promiseChain.then...? – elclanrs Commented Apr 10, 2016 at 6:34
  • Yup @elclanrs, looks like that was my problem! – l p Commented Apr 10, 2016 at 12:31
Add a ment  | 

1 Answer 1

Reset to default 10

You just attached three .then() handlers to the exact same self.promiseChain promise. This is branching, not chaining. With promises, those are very different behaviors. Those are three handlers that will all be called one immediately after the other (without waiting for results) when self.promiseChain is resolved. So, the resulting three async operations will run in parallel and finish whenever they finish, thus the results you see.

If you wanted these four operations to be sequenced, then you have to actually chain them one to another, not all chained onto the same promise. Remember .then() returns a new promise and it is that returned promise that you want to chain to in order to sequence things.

You are doing this:

var p = somePromise();

p.then(fn1);
p.then(fn2);
p.then(fn3);

This will trigger fn1, fn2 and fn3 at basically the same time and fn2 will not wait for the fn1 promise to resolve.

If you want to sequence the operations, then you want this type of logic:

var p = somePromise();

p.then(fn1).then(fn2).then(fn3);

This will not execute fn2 until the fn1 promise is done and will not execute fn3 until the fn2 promise is done - thus sequencing the async operations.

Here's how it would be if they were actually sequenced one after another. You can actually run this snippet (but have patience because it takes 10 seconds to run):

var self = {};

self.promiseChain = new Promise(function (resolve, reject) {
  setTimeout(resolve, 4000);
}).then(function () {
  log(1);
});

var p = self.promiseChain.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 3000);
  }).then(function () {
    log(2);
  });
});

p = p.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 2000);
  }).then(function () {
    log(3);
  });
});
p = p.then(function () {
  return new Promise(function (resolve, reject) {
    setTimeout(resolve, 200);
  }).then(function () {
    log(4);
  });
});

p.then(function() {
   // last promise is done now
   log("all done");
});

function log(x) {
  var div = document.createElement("div");
  div.innerHTML = x;
  document.body.appendChild(div);
}

See these other similar answers:

Execute native js promise in series

Understanding javascript promises; stacks and chaining

Is there a difference between promise.then.then vs promise.then; promise.then

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742391441a4435092.html

相关推荐

  • javascript - ES6 promise execution order - Stack Overflow

    I would expect the output for the following snippet to be 1, 2, 3, 4.But, the actual output order is

    4小时前
    20

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信