Javascript Async await-await是否阻止其他代码运行?
在javascript中,是否等待块代码?例如,假设我们有以下代码: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")
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将其视为异步操作,并在转到下一行之前“等待”它完成。您可以在集合中移动代码