如何预测Promise的异步性质

时间:2016-02-02 13:37:59

标签: javascript asynchronous promise

我有一段代码示例,我无法预测代码的流程。

var x = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve([1, 2, 3]);
    }, 0);
  });
};

x().then((val) => {
  console.log(val);
}).catch((err) => {
  console.log(err.message);
});

console.log("hello");

for (var i = 0; i < 10; i++) {
  console.log(i);
}

var y = Promise.all([Promise.resolve(1), Promise.reject(Error("err"))]);

y.then((arr) => {
    console.log(arr);
  })
  .catch((err) => {
    console.log(err);
  });

Promise.resolve('ta-da!')
  .then((result) => {
    console.log('Step 2 received ' + result);
    return 'Greetings from step 2';
  })
  .then((result) => {
    console.log('Step 3 received ' + result);
  })
  .then((result) => {
    console.log('Step 4 received ' + result);
    return Promise.resolve('fulfilled value');
  })
  .then((result) => {
    console.log('Step 5 received ' + result);
    return Promise.resolve();
  })
  .then((result) => {
    console.log('Step 6 received ' + result);
  });

日志按以下顺序排列:

"hello"
0
1
2
3
4
5
6
7
8
9
"Step 2 received ta-da!"
"Step 3 received Greetings from step 2"
"err"
"Step 4 received undefined"
"Step 5 received fulfilled value"
"Step 6 received undefined"
[1, 2, 3]

for循环按预期执行。 setTimeout()按预期工作,并在事件循环后履行承诺。

另外两个承诺相互冲突。 我期待这些承诺会立即同步,结果将是

"hello"
    0
    1
    2
    3
    4
    5
    6
    7
    8
    9
    "err"
    "Step 2 received ta-da!"
    "Step 3 received Greetings from step 2"
    "Step 4 received undefined"
    "Step 5 received fulfilled value"
    "Step 6 received undefined"
    [1, 2, 3].

即使承诺被解决为异步。它们是如何相互碰撞的。

附带截图。

enter image description here

2 个答案:

答案 0 :(得分:1)

我会回答一个设计点而不是像这样的空白测试:

承诺的目标是并行地发出异步请求,例如服务器请求。

因此,他们解决的时间顺序将取决于服务器答案,而不是broswer上的javascript客户端循环。

根据设计,不能令人满意的请求流程是可预测的。这对于一切异步都是如此。

因此,如果你需要另外一个请求,你需要等到解决第一个承诺,然后再做另一个。如果您需要独立操作,比如加载具有独立组件的仪表板,您可以同时触发所有异步请求。 无论解决了什么顺序,您都不会遇到任何问题,在仪表板的情况下,您是否真的关心第一个组件在第二个组件之前加载,显示完全独立的信息?当然不是。

现在,如果你只是想知道它是如何在浏览器中实现的,我只是说如果改变broswer它可能会改变,所以它完全不相关。你必须让你的javascript在多个浏览器上工作。

答案 1 :(得分:1)

您的代码中有三个单独的承诺链:

  1. x()开头且由于超时而花费时间最长的
  2. y(来自Promise.all(…))开头的错误引发的错误
  3. Promise.resolve('ta-da!')
  4. 开头的那个

    他们不会等待对方 - 你没有告诉他们这样做,他们也不会自己神奇地做到这一点。
    相反,它们的流是任意交错,就像标准异步函数的情况一样(想想两个具有不同周期的setInterval)。

      

    我期待这些承诺能够立即同步充实

    没有。即使承诺已经解决,承诺回调始终(可靠)异步。