gpt4 book ai didi

javascript - 为什么这个循环每次迭代重复两次?

转载 作者:行者123 更新时间:2023-12-05 00:30:54 24 4
gpt4 key购买 nike

下面的函数将每个数字打印两次。有人可以解释它是如何工作的吗?我尝试调试,但我只能看到 i 的值仅在每第二次迭代时增加。

async function run(then) {
for (let i = 1; i <= 10; i++) {
console.log(i);
then = await { then };
}
}

run(run);

具体来说,有两点我不明白。
  • 为什么i每次迭代都不会增加?
  • then = await { then }; 是什么意思究竟是做什么的?我的第一个猜测是它会等待对 run 的嵌套异步调用。在进行下一次迭代之前完成,但情况似乎并非如此。
  • 最佳答案

    我们可以通过轻微的重写以包括日志记录使这一点更清晰:

    async function run(callback) {
    let then = callback;
    for (let i = 1; i <= 10; i++) {
    console.log(callback === run ? "A" : "B", i);
    then = await { then };
    }
    }

    run(run);
    .as-console-wrapper { max-height: 100% !important; }

    这表明实际上启动了两个循环。为简单起见,仅称为 A 和 B。它们记录和 await这意味着它们的日志交错并导致 A 1、B 1、A 2、B 2 等。
    这是因为第一条语句: run(run) .它将与回调相同的函数传递给自身。这不会调用回调,但它是解决此问题的第一步。

    了解正在发生的事情的下一步是 await .您可以 await任何值(value),在大多数情况下,如果它不是一个 promise ,那也没关系。如果您有 await 42;它只是假装值为 Promise.resolve(42)并在下一个滴答声中立即继续操作。对于大多数非 promise 都是如此。唯一的异常(exception)是 thenables - 具有 .then() 的对象方法。
    当等待 thenable 时,它​​的 then()方法被调用:

    const thenable = {
    then() {
    console.log("called");
    }
    };

    (async () => {
    await thenable;
    })()

    然后解释了 await { then }陈述。这使用了 { then: then } 的简写。在哪里 then是传递给 run 的回调吗? .因此,它创建了一个 thenable 对象,该对象在等待时将执行回调。
    这意味着第一次 run()被执行并且在循环 A 的第一次迭代中,代码实际上是 await { then: run }这将执行 run再次开始循环B。 then 的值每次都被覆盖,因此为什么它只并行运行两个循环,而不是更多。

    thenables 还有更多与完全掌握此代码相关的内容。我之前展示了一个简单的,它只是显示等待它调用该方法。然而,实际上 await thenable将调用 .then()有两个参数 - 可以调用成功和失败的函数。与 Promise 构造函数一样。

    const badThenable = {
    then() {
    console.log("bad called");
    }
    };

    (async () => {
    await badThenable;
    console.log("never reached");
    })();

    const goodThenable = {
    then(resolve, reject) { //two callbacks
    console.log("good called");
    resolve(); //at least one needs to be called
    }
    };

    (async () => {
    await goodThenable;
    console.log("correctly reached");
    })();

    这是相关的,因为 run()期待回调,当 await { then: run }执行它调用 run(builtInResolveFunction)然后传递给下一个 await { then: builtInResolveFunction }进而解决导致 await解决。

    撇开这一切不谈,交错的日志记录只是任务如何解决的一个因素:

    (async () => {
    for (let i = 1; i <= 10; i++){
    console.log("A", i);
    await Promise.resolve("just to force a minimal wait");
    }
    })();

    (async () => {
    for (let i = 1; i <= 10; i++) {
    console.log("B", i);
    await Promise.resolve("just to force a minimal wait");
    }
    })();

    如果有两个异步函数正在运行并且没有什么可以真正等待:
  • 一个会一直运行,直到它到达 await然后将被暂停。
  • 另一个会一直运行直到它到达 await然后将被暂停。
  • 重复 1. 和 2. 直到没有更多的等待。
  • 关于javascript - 为什么这个循环每次迭代重复两次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71243845/

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