gpt4 book ai didi

javascript - "for await of"的控制流程是什么?

转载 作者:行者123 更新时间:2023-12-04 13:52:37 24 4
gpt4 key购买 nike

(英语不是我的母语,所以如果你发现任何英语,请提前原谅我)
在这一点上,我对 Promises 和 Async await 函数非常满意,我也知道如何使用 Promise.all (它只是等待里面的所有 Promise 先解决,然后从所有 Promise 中提取值,然后返回一个数组使用带有这些值的 .then 函数。)
现在我想知道如何等待引擎盖下的工作。
我刚刚写了这段代码:

async function f() {

let p1 = new Promise(function (r) {
setTimeout(r, 3000, 1)
})

let p2 = new Promise(function (r) {
setTimeout(r, 2000, 2)
})

let p3 = new Promise(function (r) {
setTimeout(r, 1000, 3)
})

let arrayOfPromises = [p1, p2, p3];

for await (let p of arrayOfPromises) {
let data = await p;
console.log(data)
}
}

f();

现在我的问题是当它到达第一次迭代时会发生什么,它将到达一个 await 关键字,并且 await 立即返回一个待处理的 promise , 那么下面的代码是否在技术上评估为每次迭代中的未决 promise ?
  {
let data = await p;
console.log(data)
}
所以我很困惑到底发生了什么,对于第一次迭代,setTimeout 将注册 3 秒,第二次注册 2,第一次注册 1。由于我们没有同步代码,所有的回调将一个一个运行,p3将首先被解析,然后是p2,最后是p1!
现在直观地说,我认为一旦 p1、p2、p3 被解析,这段代码“console.log(data)”将被放入微任务队列,因为我们的 p3 先被解析,我们应该得到 3,2,1 但我们'重新获得 1、2、3,那么我的理解中缺少什么?
(显然代码没有放入微任务队列,它的功能可能会像生成器函数一样执行类似 .next() 的操作,但我认为这在这里无关紧要)
似乎对于等待,第一个 promise 将首先被记录,无论它与迭代中的其他 promise 相比解决得有多快或多晚,那么到底发生了什么?

最佳答案

这是一个可以按您预期工作的代码:

async function printWhenResolved(p) { 
const data = await p; console.log(data)
}

function createIteratorsAndBindPrinting() {

let p1 = new Promise(function (r) {
setTimeout(r, 3000, 1)
})

let p2 = new Promise(function (r) {
setTimeout(r, 2000, 2)
})

let p3 = new Promise(function (r) {
setTimeout(r, 1000, 3)
})

let arrayOfPromises = [p1, p2, p3];

for (let p of arrayOfPromises) {
printWhenResolved(p)
}
console.log('end of createIteratorsAndBindPrinting')
}
createIteratorsAndBindPrinting()
现在,从语义上讲,我认为处理看起来很清楚。在“for await (... of ...)”上,迭代一个可迭代对象,在每个点根据迭代的当前值是同步还是异步提供其值来做出决定。如果它同步提供它的值,我们立即执行“for”中的代码块。如果它异步提供它的值,我们等到提供了值,然后调用“for”中的 block 。
所以我们依次等待每个可迭代 - 然后才离开 for -堵塞。
在我提供的代码中,我们改为在每个 Promise 上调用一个异步函数,当它解析后,会将值记录到控制台。这也是为什么您的 let data = await p是多余的(因为您的 await 也在 for -construct 中)。
这样, async函数是一种组织响应式代码的方法(即调用过程的代码以及例如 promise 的解析),而无需回调 hell 或 then-chaining。这可以说允许更多的模块化、表达性和可测试性。另见 https://stackoverflow.com/a/54497100/16005185
要查看与您的代码具体做什么的区别(没有冗余),请将上面的代码与以下代码进行比较:
async function createIteratorsAwaitAndPrint() {   

let p1 = new Promise(function (r) {
setTimeout(r, 3000, 1)
})

let p2 = new Promise(function (r) {
setTimeout(r, 2000, 2)
})

let p3 = new Promise(function (r) {
setTimeout(r, 1000, 3)
})

let arrayOfPromises = [p1, p2, p3];

for await (let p of arrayOfPromises) {
console.log(p)
}
console.log('end of createIteratorsAwaitAndPrint')
}
createIteratorsAwaitAndPrint()
在这里我们做 await在 for 构造中。注意“end of [...]”日志在我们完成迭代之前不会发生。

关于javascript - "for await of"的控制流程是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67961004/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com