异步函数 - 等待不等待承诺

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】:

这是我使用带有 resolvereject 的 Promise 处理 awaitasync 的例程机制

    // 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 在执行以下代码之前“神奇地”解开一个承诺。代码看起来是同步的,但它不是同步执行的。

以上是关于异步函数 - 等待不等待承诺的主要内容,如果未能解决你的问题,请参考以下文章

在自定义承诺上使用异步等待

在自定义承诺上使用异步等待

使用异步/等待与承诺的区别?

在映射下一项之前,异步等待映射不等待异步函数在映射函数内部完成

需要帮助在 NodeJS 中使用 Sinon 存根异步 / 等待承诺

Javascript - 异步等待和获取 - 返回值,而不是承诺?