首页 > 解决方案 > 为什么我需要使用 async/await 两次来使这个非阻塞?

问题描述

我有两个函数,第一个是主函数,它有 switch 语句调用第二个是异步的。如果我的第二个功能是异步的,那不是非阻塞的吗?我是否仍然必须使第一个异步以使其成为非阻塞,如果是这样,为什么?

例子

exports.funcOne = async (theParam) => { // async ??
    switch (theParam) {
        case 'hey':
            return await funcTwo()
       default:
            ...
    }
}

const funcTwo = async () => {
   await axios.get...
}

标签: javascriptnode.js

解决方案


一般来说,所有包含的函数都await必须是async.

如果我们想象它不存在,并且您可以在同步函数中等待异步结果,那么该规则可能更有意义。

首先,我们需要了解关于函数的一件重要事情:

它们必须运行到完成,或者换句话说:一个常规函数运行到它完成,return并且没有其他代码可以同时运行

如果我们可以await在一个非异步函数内部,这意味着我们将阻止执行,直到等待的 promise 解决,因为在此期间没有其他代码可以运行。由于解决 promise 的代码也无法运行,我们创建了一个死锁。

async functions 只运行到完成,直到达到await. 因此,当axios.get(...)被调用时,promise 会从它同步返回,funcTwo 停止执行,返回一个 promise 本身,因此funcOne也停止执行(这可能是它的原因async)。然后引擎可以继续处理其他事情,并且当底层请求完成时,承诺解决,funcTwo继续执行解决它返回的承诺,funcOne继续执行并解决返回的承诺。

如果我的第二个功能是异步的,那不是非阻塞的吗?

这实际上取决于您对non-blocking的定义。一般来说,执行的每一个 JS 代码都会“阻塞线程”(因为一次只能执行一个函数),但由于大多数任务非常小,你不会注意到阻塞。

Anasnyc function也是阻塞的,只要它不停止承诺解决。然后它处于非阻塞等待状态。

异步任务(例如执行网络请求)也不会阻塞,因为它们由引擎处理(卸载到其他线程或硬件等)。


推荐阅读