gpt4 book ai didi

javascript - 为什么 await 之后的代码没有立即运行?它不应该是非阻塞的吗?

转载 作者:可可西里 更新时间:2023-11-01 01:47:38 32 4
gpt4 key购买 nike

我很难理解 async 和 await 在幕后是如何工作的。我知道我们有 promise ,通过使用“then”函数可以使我们的代码成为非阻塞代码,我们可以在 promise 得到解决后放置我们需要做的所有工作。以及我们想要并行进行的工作,以保证我们只是将它写在我们的 then 函数之外。因此代码变得非阻塞。但是我不明白 async await 是如何生成非阻塞代码的。

async function myAsyncFunction() {
try {
let data = await myAPICall('https://jsonplaceholder.typicode.com/posts/1');
// It will not run this line until it resolves await.
let result = 2 + 2;
return data;
}catch (ex){
return ex;
}
}

参见上面的代码。在 API 调用得到解决之前,我无法继续前进。如果它使我的代码阻塞代码,那么它比 promise 更好吗?还是我错过了关于 asyncawait 的某些内容?我应该把不依赖于 await 调用的代码放在哪里?这样它就可以继续工作而无需 await 暂停执行?

我正在添加我想在异步等待示例中复制的 Promise 代码。

function myPromiseAPI() {
myAPICall('https://jsonplaceholder.typicode.com/posts/1')
.then(function (data) {
// data
});
// runs parallel
let result = 2 + 2;
}

最佳答案

正如其名称所暗示的那样,await 关键字将导致函数“等待”,直到它的 promise 在执行下一行之前解决。 await 的全部要点是让代码等待操作完成后再继续。

此代码与阻塞代码之间的区别在于,函数外部的世界可以在函数等待异步操作完成时继续执行。

asyncawait 只是 promises 之上的语法糖。它们允许您编写看起来很像普通同步代码的代码,即使它在幕后使用了 promise 。如果我们在那里将您的示例翻译成明确适用于 promise 的东西,它看起来像:

function myAsyncFunction() {
return myAPICall('https://jsonplaceholder.typicode.com/posts/1')
.then(function (data) {
let result = 2 + 2;
return data;
})
.catch(function (ex) {
return ex;
});
}

正如我们在这里看到的,let result = 2 + 2; 行位于 .then() 处理程序中,这意味着它不会执行直到 myAPICall() 已解决。当你使用 await 时也是一样的。 await 只是为您抽象出 .then()

要记住的一件事(我认为您正在寻找的要点)是您不必立即使用 await。如果您这样编写函数,那么您可以立即执行 let result = 2 + 2; 行:

const timeout = 
seconds => new Promise(res => setTimeout(res, seconds * 1000));

function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}

async function myAsyncFunction() {
try {
console.log('starting');

// just starting the API call and storing the promise for now. not waiting yet
let dataP = myAPICall('https://jsonplaceholder.typicode.com/posts/1');

let result = 2 + 2;

// Executes right away
console.log('result', result);

// wait now
let data = await dataP;

// Executes after one second
console.log('data', data);

return data;
} catch (ex) {
return ex;
}
}

myAsyncFunction();

经过一些澄清,我可以看出您真正想知道的是如何避免必须一个接一个地等待两个异步操作,而是让它们并行执行。实际上,如果您在另一个之后使用一个 await,则第二个将在第一个完成之前开始执行:

const timeout = 
seconds => new Promise(res => setTimeout(res, seconds * 1000));

function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}

async function myAsyncFunction() {
try {
console.log('starting');

let data1 = await myAPICall('https://jsonplaceholder.typicode.com/posts/1');
// logs after one second
console.log('data1', data1);

let data2 = await myAPICall('https://jsonplaceholder.typicode.com/posts/2');
// logs after one more second
console.log('data2', data2);
} catch (ex) {
return ex;
}
}

myAsyncFunction();

为了避免这种情况,您可以做的是启动两个异步操作,方法是在不等待它们的情况下执行它们,将它们的 promise 分配给一些变量。然后你可以等待两个 promise :

const timeout = 
seconds => new Promise(res => setTimeout(res, seconds * 1000));

function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}

async function myAsyncFunction() {
try {
console.log('starting');
// both lines execute right away
let dataP1 = myAPICall('https://jsonplaceholder.typicode.com/posts/1');
let dataP2 = myAPICall('https://jsonplaceholder.typicode.com/posts/2');

let data1 = await dataP1;
let data2 = await dataP2;

// logs after one second
console.log('data1', data1);
console.log('data2', data2);
} catch (ex) {
return ex;
}
}

myAsyncFunction();

另一种方法是使用 Promise.all() 进行一些数组分解:

const timeout = 
seconds => new Promise(res => setTimeout(res, seconds * 1000));

function myAPICall() {
// simulate 1 second wait time
return timeout(1).then(() => 'success');
}

async function myAsyncFunction() {
try {
console.log('starting');

// both myAPICall invocations execute right away
const [data1, data2] = await Promise.all([
myAPICall('https://jsonplaceholder.typicode.com/posts/1'),
myAPICall('https://jsonplaceholder.typicode.com/posts/2'),
]);

// logs after one second
console.log('data1', data1);
console.log('data2', data2);
} catch (ex) {
return ex;
}
}

myAsyncFunction();

关于javascript - 为什么 await 之后的代码没有立即运行?它不应该是非阻塞的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43302584/

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