异步函数 - 等待不等待承诺
Posted
技术标签:
【中文标题】异步函数 - 等待不等待承诺【英文标题】:async function - await not waiting for promise 【发布时间】:2018-02-03 05:10:29 【问题描述】:我正在尝试学习异步等待。在这段代码中 -
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());
为什么我的输出是 -
Promise <pending>
而不是一些价值? getResult()
函数不应该等待 myFun()
函数解析它的承诺值吗?
【问题讨论】:
异步函数总是返回一个承诺。 getResult 正在等待 myFunc 解决。然后它在 promise 中返回值。 【参考方案1】:这是我使用带有 resolve 和 reject 的 Promise 处理 await 和 async 的例程机制
// 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);)
希望能为某人节省宝贵的时间
【讨论】:
【参考方案2】:你需要明白的是,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))
或者在另一个函数中使用时,你可以简单地再次使用'await'
async callingFunction()
console.log(await(getResult());
【讨论】:
很好的解释!您可以在此处查看运行示例:codepen.io/juanmamenendez15/pen/YzPqeKj?editors=0012【参考方案3】:如果您使用的是 async/await,则所有调用都必须使用 Promises 或 async/await。您不能只是神奇地从同步调用中获得异步结果。
您的最终电话需要是:
getResult().then(response => console.log(response));
或者类似的东西:
(async () => console.log(await getResult()))()
【讨论】:
为什么最后一个异步(带有 IIFE 的那个)变成同步的,而不是我的getResult()
方法?
@hg_git 因为它被包裹在一个异步 IIFE 中,带有一个 await 调用。它不会变得同步,它只是语法糖。
我的getResult()
也有async
关键字,还有一个await
调用......
两种黑白有什么区别?
@hg_git: async
函数返回承诺。 await
在执行以下代码之前“神奇地”解开一个承诺。代码看起来是同步的,但它不是同步执行的。以上是关于异步函数 - 等待不等待承诺的主要内容,如果未能解决你的问题,请参考以下文章
在映射下一项之前,异步等待映射不等待异步函数在映射函数内部完成