Javascript Async await-await是否阻止其他代码运行?

Javascript Async await-await是否阻止其他代码运行?,javascript,async-await,Javascript,Async Await,在javascript中,是否等待块代码?例如,假设我们有以下代码: async function queryDB() { const addUser = await promisePool.execute("INSERT INTO Users (User) VALUES ('username')") const selectUser = await promisePool.execute("SELECT User FROM Users")

在javascript中,是否等待块代码?例如,假设我们有以下代码:

async function queryDB() {
    const addUser = await promisePool.execute("INSERT INTO Users (User) VALUES ('username')")
    const selectUser = await promisePool.execute("SELECT User FROM Users") 
}
是否将“selectUser”等待运行,直到addUser完成,以便我们可以选择添加的用户?

另外,假设我们在等待之间添加了一些不是承诺的代码,比如:

    async function queryDB() {
        const addUser = await promisePool.execute("INSERT INTO Users (User) VALUES ('username')")

setTimeout(() => console.log('Do something that takes 3 seconds'), 3000);

        const selectUser = await promisePool.execute("SELECT User FROM Users") 
    }
是否“selectUser”会等待addUser而不是setTimeout?如果是这样,您将如何编写上述代码,使addUser先运行,然后设置Timeout,然后选择User?

我还想补充一点,我一直在学习和阅读stackoverflow和其他资源,但我需要一些澄清。

是否将“selectUser”等待运行,直到addUser完成,以便我们可以选择添加的用户?

是否“selectUser”会等待addUser而不是setTimeout?如果是这样,您将如何编写上述代码,使addUser先运行,然后设置Timeout,然后选择User?

“selectUser”将在“addUser”之后执行,但不会执行setTimeout回调。如果要在setTimeout之后运行“selectUser”,可以将其添加到setTimeout回调函数中。所以它应该看起来像:

异步函数queryDB(){ const addUser=await promisePool.execute(“插入用户(User)值('username')”) setTimeout(异步()=>{ const selectUser=wait promisePool.execute(“从用户中选择用户”); }, 3000); } “selectUser”将等待运行,直到addUser完成,以便我们可以 选择要添加的用户

wait表达式导致异步函数执行暂停,直到 承诺已解决(即履行或拒绝),并恢复 完成后执行异步函数。会议恢复后 等待表达的价值是履行承诺的价值

执行
queryDB
函数将在等待第一个承诺解决时暂停。第二行代码将仅在第一行代码成功完成后执行

“selectUser”会等待addUser而不是setTimeout吗

是的,没错

如果是这样,您将如何编写上面的代码以使addUser首先运行,然后 设置超时,然后选择用户

您可以将
setTimeout
包装在一个函数中,该函数返回一个承诺,然后等待该承诺,以确保前两行完成后执行最后一行

下面是包装
setTimeout

function waitForTimeout(seconds) {
  return new Promise((resolve, reject) => {
     setTimeout(() => { 
        console.log("Hello World");
        resolve();
     }, seconds * 1000);        
  });
}
一旦有了包装器函数,您可以
等待它,如下所示:

async function queryDB() {
    const addUser = await promisePool.execute(
        "INSERT INTO Users (User) VALUES ('username')"
    );

    await waitForTimeout(3);    // wait for 3 seconds

    const selectUser = await promisePool.execute("SELECT User FROM Users") 
}

简言之,答案是肯定的,它会阻塞。wait的目的是确保在下一行中有可用的结果。因此,如果您需要addUser的值来进行下一次查询,那么您将拥有它


它的引入是为了让您不必在第一行末尾编写then(),然后将第二个调用放入回调,这样代码就很难阅读。

重要注意:blocks在这里可能是个不好的词。更好的说法是等待。更好的做法可能是只说使用
wait
语法完成的操作保证按顺序执行

大局

在Node中使用异步代码的主要原因是,当我们等待一些异步操作(如数据库请求、网络请求、文件操作等)时,我们不会阻止整个应用程序。我们只会阻止这个特定的执行上下文

尽管Node.js只使用一个线程来执行用户代码,但I/O操作是异步的,并且它们是非阻塞的

因此,假设您有一个端点,上面的代码链接到前端的某个按钮“添加用户”

  • 比尔按下按钮,您开始处理请求,开始等待
    addUser
    操作
  • 此时,约翰也按下了同样的按钮。您的代码仍将被执行,并将开始等待,直到
    addUser
    完成
  • 假设
    Users
    table陷入了死锁,任何数据库操作都会非常慢,我们还有第三个用户Jane,她正在浏览您的站点,但她不需要登录/注册,因此她不会触摸
    Users
    table。会发生什么?简很好,她的请求会顺利通过的
如何等待设置超时

setTimeout
来自“前一个时代”,因此它使用回调而不是异步/等待语法。但是,如果需要的话,总是可以将回调样式转换为async/await

功能延迟(ms){
返回新承诺(resolve=>setTimeout(resolve,ms));
}
等待延迟(5000);

简而言之,wait只会在当前异步函数中阻塞wait语句之后的代码,而不是整个线程。一旦等待被解决,剩下的代码就会被执行。在您的示例中,由于您有2条WAIT语句,因此第二条语句在第一条语句完成之前不会运行,因为第一条语句阻塞了两条WAIT语句所在的函数。对于第二个示例,由于
setTimeout()
不会返回承诺,而且您也不会等待它,因此函数将其视为“同步”操作。也就是说,它将把
setTimeout()
回调抛出到调用堆栈中,直到下一个事件循环,并继续执行下一行,这是另一个等待语句,它将再次阻塞函数,直到解析为止


为了一行一行地执行所有三行,您必须将
setTimeout()
放入承诺中并等待它,以便JS将其视为异步操作,并在转到下一行之前“等待”它完成。

您可以在集合中移动代码