trong>直到异步函数用一个值“解析”或用一个错误“拒绝”,但它不会阻止javascript引擎,如果它在等待时有其他事情要做,它仍然可以做其他事情

trong>直到异步函数用一个值“解析”或用一个错误“拒绝”,但它不会阻止javascript引擎,如果它在等待时有其他事情要做,它仍然可以做其他事情,javascript,async-await,Javascript,Async Await,是的,循环将按顺序执行 关于这一切,在上有一个很棒的教程。这是我关于这个有趣问题的测试解决方案: import crypto from "crypto"; function diyCrypto() { return new Promise((resolve, reject) => { crypto.pbkdf2('secret', 'salt', 2000000, 64, 'sha512', (err, res) => { if (e

是的,循环将按顺序执行


关于这一切,在上有一个很棒的教程。

这是我关于这个有趣问题的测试解决方案:

import crypto from "crypto";

function diyCrypto() {
    return new Promise((resolve, reject) => {
        crypto.pbkdf2('secret', 'salt', 2000000, 64, 'sha512', (err, res) => {
            if (err) {
                reject(err)
                return 
            }
            resolve(res.toString("base64"))
        })
    })
}

setTimeout(async () => {
    console.log("before await...")
    const a = await diyCrypto();
    console.log("after await...", a)
}, 0);

setInterval(() => {
    console.log("test....")
}, 200);

在setTimeout的回调中,
wait
阻止执行。但是
setInterval
正在保持运行,因此事件循环照常运行

你真的试过了吗?是的,我得到了一个连续的结果。我不确定这是否是巧合(异步函数实际上很快)。我不确定是否将所有异步函数调用推送到一个数组中,然后执行一个
wait Promise.all(arr)
,或者此表单是否正确,以及是否有其他东西阻碍了所需的异步性。如果我为所有人做一个
wait
,那么我就必须进入
Promise.map
来处理每一个。这让我怀疑在这种情况下,
是否比async/await好。JS是确定性的。无论函数是异步的还是非异步的,它都不依赖于执行某个东西的“速度”。关于
Promise.all
,它会做一些不同的事情-它是否仍然正确(或者更可取)取决于您的要求。当执行涉及外部资源(例如数据库、文件i/o)的
async
操作时,函数的运行时间是不确定的。是的,但只要它是异步的,它永远不会立即调用回调,并且总是先运行到同步代码完成。这个答案实际上并没有回答这个问题。这毫无意义。您的
promisesToAwait
数组永远不会包含承诺。它不会阻止循环,但也不会按预期执行。堆栈说明提醒我,
async/wait
直到最近才使用生成器/
yield
实现。这样想会让事情变得更清楚。我接受这个答案。@smorgs堆栈解释实际上更多地与标准承诺
有关,而不是与生成器有关。只有“跳回调用位置”和“函数状态恢复”才被理解为
yield
;我发现堆栈模型在
中是显而易见的。然后
等待
就不是这样了,所以把它看作是
收益
解决了我的困惑。这是因为您的callAPI函数没有返回承诺,所以
等待callAPI()
立即返回。如果您更改
callAPI()
以返回承诺,那么它将工作。“看到此函数在等待结果时被阻止,因此它将检查事件循环”:不,这是对所发生情况的错误陈述。当发生
wait
时,函数实际上返回,并且在函数调用后继续执行代码。@trincot具体的差别是“哪个”代码在函数调用后继续执行。是1)异步函数中继续的代码,还是2)等待后调用函数中的代码,还是3)事件循环中排队的任何其他活动。从调用函数的角度来看,它似乎被阻塞(等待承诺得到解决),从异步函数的角度来看,它正常运行(但可能等待外部I/O或其他),从节点的角度来看,它将检查事件循环,看看是否还有其他事情要做。@trincot这也是为什么我说“具有阻止运行功能的‘效果’”。它并没有真正被阻塞,节点将从事件循环中执行其他操作(以及继续执行异步函数),但从调用函数(而不是被调用的异步函数)的角度来看,它将“看起来”被阻塞。提到节点“将检查事件循环”是错误的。当遇到
wait
时,节点将不检查事件循环。函数将返回,代码将继续执行,就像任何函数调用之后一样。事件循环仅在调用堆栈为空时起作用,而在遇到
wait
时不起作用。顺便说一句:这个问题不是关于节点的,而是关于JavaScript的。你还写了“所以它会去检查事件循环(例如,新的鼠标点击,或者连接请求等)”。事实并非如此。(1) 代码执行将继续,而不考虑事件循环;(2)即使存在诸如鼠标单击之类的事件,它们也不会优先于处于不同队列(“承诺作业队列”)中的承诺作业。承诺解析(将在
等待
时恢复函数上下文)优先于鼠标单击和其他代理驱动的事件。
const promisesToAwait = [];
for (let i = 0; i < 100; i++) {
  promisesToAwait.push(fetchDataForId(i));
}
const responses = await Promise.all(promisesToAwait);
let result = await some_slow_async_function();
let promise = some_slow_async_function(); // start the slow async function
// you could do other stuff here while the slow async function is running
let result = await promise; // wait for the final value from the slow async function
import crypto from "crypto";

function diyCrypto() {
    return new Promise((resolve, reject) => {
        crypto.pbkdf2('secret', 'salt', 2000000, 64, 'sha512', (err, res) => {
            if (err) {
                reject(err)
                return 
            }
            resolve(res.toString("base64"))
        })
    })
}

setTimeout(async () => {
    console.log("before await...")
    const a = await diyCrypto();
    console.log("after await...", a)
}, 0);

setInterval(() => {
    console.log("test....")
}, 200);