MST

星途 面试题库

面试题:网络编程下JavaScript的async/await与协程式编程的关联及应用

在处理高并发网络请求的后端开发项目中,async/await如何结合协程式编程来优化性能?描述其原理,并给出一个简单的代码示例展示如何使用它们来管理多个并发的网络请求,确保资源高效利用且避免回调地狱。
49.4万 热度难度
后端开发网络编程

知识考点

AI 面试

面试题答案

一键面试

原理

  1. 协程基础:协程是一种轻量级的线程,与操作系统线程不同,它由用户态调度。在Python中,asyncio库实现了协程式编程。async def定义的函数是一个协程函数,调用它不会立即执行函数体,而是返回一个协程对象。
  2. async/await机制await只能在async def定义的函数内部使用,它用于暂停协程的执行,等待一个可等待对象(如另一个协程)完成。这样可以在一个线程内实现多个任务的协作式调度,避免阻塞主线程,提高了I/O密集型任务(如网络请求)的效率。在高并发网络请求场景下,当一个网络请求在等待响应时,协程可以暂停并切换到其他请求任务,从而充分利用CPU资源,提升整体性能。

代码示例

以下是使用Python的asyncio库结合async/await处理多个并发网络请求的示例代码:

import asyncio
import aiohttp


async def fetch(session, url):
    async with session.get(url) as response:
        return await response.json()


async def main():
    urls = [
        'https://jsonplaceholder.typicode.com/todos/1',
        'https://jsonplaceholder.typicode.com/todos/2',
        'https://jsonplaceholder.typicode.com/todos/3'
    ]
    async with aiohttp.ClientSession() as session:
        tasks = [fetch(session, url) for url in urls]
        results = await asyncio.gather(*tasks)
        print(results)


if __name__ == "__main__":
    asyncio.run(main())

在上述代码中:

  1. fetch函数是一个协程函数,用于发起一个HTTP GET请求并返回JSON格式的响应。async with语句用于管理aiohttp的会话资源,await response.json()暂停fetch协程,直到响应数据可用。
  2. main函数也是一个协程函数,它定义了要请求的URL列表,并为每个URL创建一个fetch任务。asyncio.gather函数用于并发运行这些任务,并等待所有任务完成。await asyncio.gather(*tasks)会暂停main协程,直到所有fetch任务完成,然后将所有任务的结果收集到results列表中。
  3. asyncio.run(main())用于运行整个异步程序,启动事件循环并执行main协程。