首先,我意识到我可以使用 async/await 或 Promise 链来完成此任务。我试图理解为什么以下具体不起作用。
我对这段代码的理解是,它应该进行
p1
获取,进而将 HTTP 请求发送到事件队列,并立即开始使请求异步,运行 for
循环(阻塞,下面的代码不会运行直到 for
完成),然后进行 p2
获取(此时我预计 p1
获取将完成),然后我们到达 p1.then
和 p2.then
。由于我以 p1
循环的形式给了 for
一个巨大的领先优势,我希望我们几乎总是会打印 0
。但事实并非如此。这似乎完全是不确定的。我知道存在网络条件,但我认为 for
循环给出的领先优势足以确定性地返回 0
。
这让我感觉自己的理解有差距。我想知道为什么会这样?
let x = 1;
let url = "https://www.google.com";
let p1 = fetch(url);
for (let i = 0; i < 1000000000; i++) {}
// Is it possible to ensure that the promise `p1` gets resolved earlier than `p2`? (By blocking the code here) Not working with the `for` loop.
let p2 = fetch(url);
p1.then(() => {
x = 0;
});
p2.then(() => {
x = x * 1;
// Because of the race condition between `p1` and `p2`, the value of `x` is indeterministic.
console.log(x);
});
我尝试增加
for
循环的迭代次数,但仍然得到不确定的结果。
如果您希望 Promise 的两个
.then()
按确定的顺序执行,您应该使用类似 Promise.all()
的内容来强制执行两个 Promise,然后再按定义的顺序开始进一步处理:
const url = "https://dummyjson.com/";
let p1 = fetch(url+"users/3").then(r=>r.json());
let p2 = fetch(url+"posts/7").then(r=>r.json());
Promise.all([p1,p2]).then(([u,p])=>{
console.log(`1. user: ${u.firstName} ${u.lastName}`);
console.log("2. post:",p.title);
});