[英]async function - await not waiting for promise
我正在尝试学习异步等待。 在这段代码中 -
const myFun = () => {
let state = false;
setTimeout(() => {state = true}, 2000);
return new Promise((resolve, reject) => {
setTimeout(() => {
if(state) {
resolve('State is true');
} else {
reject('State is false');
}
}, 3000);
});
}
const getResult = async () => {
return await myFun();
}
console.log(getResult());
为什么我得到 output 作为 -
Promise { <pending> }
而不是一些价值? getResult()
function 不应该等待myFun()
function 解析它的 promise 值吗?
如果您使用的是 async/await,则所有调用都必须使用 Promises 或 async/await。 您不能只是从同步调用中神奇地获得异步结果。
您的最终电话需要是:
getResult().then(response => console.log(response));
或类似的东西:
(async () => console.log(await getResult()))()
您需要了解的是,async/await 不会让您的代码同步运行,而是让您将其编写为:
简而言之:前面带有 async 的函数实际上是异步执行的,因此使用了关键字“async”。 并且“await”关键字将使在此异步函数中使用它的那行在其执行期间等待承诺。 因此,尽管线路等待,但整个函数仍然异步运行,除非该函数的调用者也“等待”......
更详细的解释:当你把 async 放在一个函数前面时,实际上是让它返回一个带有该函数返回的任何内容的 Promise。 该函数异步运行,当执行 return 语句时,promise 会解析返回值。
意思是,在您的代码中:
const getResult = async () => {
return await myFun();
}
函数“getResult()”将返回一个 Promise,一旦它完成执行就会解决。 所以 getResult() 函数内的行是异步运行的,除非你告诉调用 getResult() 的函数也为它“等待”。 在 getResult() 函数中,您可能会说它必须等待结果,这使得 getResult() 的执行等待它解决 promise,但 getResult() 的调用者不会等待,除非您也告诉调用者“等待” '。
所以一个解决方案是调用:
getResult().then(result=>{console.log(result)})
或者在另一个函数中使用时,您可以简单地再次使用“等待”
async callingFunction(){
console.log(await(getResult());
}
这是我使用带有解析和拒绝机制的Promise处理等待和异步的例程
// step 1 create a promise inside a function
function longwork()
{
p = new Promise(function (resolve, reject) {
result = 1111111111111 // long work here ;
if(result == "good"){
resolve(result);
}
else
{
reject("error ...etc")
}
})
return p
}
// step 2 call that function inside an async function (I call it main)and use await before it
async function main()
{
final_result = await longwork();
//..
}
//step 3 call the async function that calls the long work function
main().catch((error)=>{console.log(error);})
希望可以节省一些宝贵的时间
在实际情况下,异步和等待没有意义:
Promise.resolve(3).then(console.log); console.log(4);
4
3
换句话说,由于 then() fork 和运行比后续语句慢(即使对于已解决的 Promise),那么我们需要将后续语句放在 then 中,例如:
Promise.resolve(3).then(_ => { console.log(_); console.log(4); });
3
4
既然这是真的,那为什么还要等待。 所以我还没有看到为什么 async 和 await 存在。
本次讨论中未提及的是该行为的用例含义。 在我看来,关键是要考虑您打算从顶层对 output 做什么,真正异步的 function,以及您打算在哪里做。
如果您计划立即使用 output,即在等待顶级异步 function 返回的“异步”function 中,并且您对 output 所做的操作对调用堆栈中更深层的其他函数没有任何影响,那么它更深层次的功能已经转移并不重要。 但是如果 output 需要在调用堆栈的更深处,那么您需要使用“异步”函数在堆栈中一直等待调用到该点。 一旦您到达调用堆栈中 function 不关心异步 output 的点,您就可以停止使用异步函数。
例如,在下面的代码中,function B 使用从 function A 返回的内容,因此被声明为“async”并等待 A()。 Function C() 调用 B(),返回 Promise,但可以在 promise 解析之前直接继续,因为它对 A() 的内容不感兴趣,也不关心它做了什么。 所以C不需要声明为async,也不需要await B()。
function A() {
return new Promise((resolve, reject) => {
//do something slow
resolve (astuff)
}
}
async function B() {
var bstuff = await A();
dosomethingwith(bstuff);
return;
}
function C() {
B();
dontwaitmoveon();
...
return;
}
在下一个示例中,C() 确实使用了 A() 的内容,因此需要等待它。 C() 必须声明为“异步”并等待 B()。 然而 D() 不关心 A() 的东西,也不关心它做了什么,所以一旦 C() 返回它的 promise 就继续前进。
function A() {
return new Promise((resolve, reject) => {
//do something slow
resolve (astuff)
}
}
async function B() {
var bstuff = await A();
dosomething();
return bstuff;
}
async function C() {
var cstuff = await B();
dosomethingwith(cstuff);
...
return;
}
function D() {
C();
dontwaitmoveon();
...
return;
}
自从弄清楚这一点后,我尝试设计我的代码,以便尽可能接近源使用异步 function 返回的内容。
尽管您的“ getResult ”函数是异步的,并且您正确地对 myFun 进行了 await 调用,但请查看调用getResult函数的位置,它位于任何异步函数之外,因此它是同步运行的。
所以既然getResult是从同步的角度调用的,那么只要调用,Javascript 就会同步获取当前可用的任何结果,这是一个 Promise。
因此,异步函数的返回不能被强制等待(非常重要),因为它们与调用的来源地是同步的。
要获得您想要的,您可以运行以下命令,
async function getResult() {
const result = await myFun();
console.log(result);
//see no returns here
}
getResult();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.