ES6承诺执行顺序 [英] ES6 promise execution order

查看:137
本文介绍了ES6承诺执行顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望以下代码段的输出为1, 2, 3, 4.但是,实际的输出顺序是1, 4, 3, 2.

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.net/imu5bhoj/

我所读到的所有关于Promise的信息都表明,应该有可能像这样在扁平"链中获得所需的订单.显然我缺少一些细节吗?有人可以帮我指出正确的方向吗?

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?

这是一个小提琴( http://www.es6fiddle.net/imu6vh1o/)以一种非固定的方式进行操作,但是很难进行推理并且使顺序链接变得笨拙.

Here's a fiddle (http://www.es6fiddle.net/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).

推荐答案

您刚刚将三个.then()处理程序附加到了完全相同的self.promiseChain承诺.这是分支,而不是链接.有了承诺,那是非常不同的行为.这三个处理程序在解析self.promiseChain时将在另一个处理程序之后立即被调用(无需等待结果).因此,产生的三个异步操作将并行运行,并在完成后立即完成,因此您将看到结果.

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.

如果您希望对这四个操作进行排序,那么您实际上必须将它们彼此链接在一起,而不是全部链接到相同的Promise上.请记住,.then()返回一个新的promise,它是您要链接以对事物进行排序的那个promise.

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.

您正在这样做:

var p = somePromise();

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

这将基本上同时触发fn1fn2fn3,并且fn2不会等待fn1承诺解决.

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

这将在fn1承诺完成之前不执行fn2,并且在fn2承诺完成之前不会执行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.

这就是如果将它们实际上一个接一个地排序的情况.您实际上可以运行此代码段(但要耐心等待,因为它需要10秒钟才能运行):

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);
}

查看其他类似的答案:

依次执行本机js承诺

了解JavaScript承诺;堆栈和链接

promise.then.then与promise.then之间是否有区别?答应.然后

这篇关于ES6承诺执行顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆