前端工程师学Python异步,有先天优势——因为你已经被Promise折磨过了。

JS异步 vs Python异步:一张表说清

维度 JavaScript Python
底层机制 Event Loop(单线程) asyncio Event Loop(单线程)
异步标记 async function async def
等待 await promise await coroutine
并发执行 Promise.all() asyncio.gather()
创建异步任务 new Promise() asyncio.create_task()
定时器 setTimeout() asyncio.sleep()
HTTP请求 fetch() aiohttp / httpx

核心区别:Python的协程不会自动执行

这是最容易踩的坑。JS里写async function调用就自动返回Promise开始执行了,但Python里:

import asyncio

async def fetch_data():
    print("开始请求...")
    await asyncio.sleep(1)  # 模拟网络请求
    return {"data": "Hello AI"}

# 错误!这只是创建了协程对象,不会执行
result = fetch_data()  # <coroutine object>

# 正确!必须用await或asyncio.run()
result = asyncio.run(fetch_data())
print(result)  # {"data": "Hello AI"}

并发请求:Promise.all() vs asyncio.gather()

import asyncio

async def call_api(name, delay):
    print(f"[{name}] 开始请求...")
    await asyncio.sleep(delay)
    print(f"[{name}] 完成!耗时{delay}s")
    return f"{name}的结果"

async def main():
    # 类似 Promise.all()
    results = await asyncio.gather(
        call_api("DeepSeek", 1),
        call_api("通义千问", 1.5),
        call_api("Claude", 2)
    )
    print(f"全部完成: {results}")

asyncio.run(main())
# 总耗时约2s(并发),而非4.5s(串行)

Pydantic类型校验:比PropTypes强100倍

from pydantic import BaseModel, Field
from typing import Optional

# 类似TypeScript的interface,但会在运行时校验
class ChatMessage(BaseModel):
    role: str = Field(..., pattern="^(system|user|assistant)__CODE_BLOCK_2__quot;)
    content: str = Field(..., min_length=1, max_length=4096)
    temperature: Optional[float] = Field(0.7, ge=0, le=2)

# 自动校验,错误类型直接报错
msg = ChatMessage(role="user", content="你好")
print(msg.model_dump())  # {'role': 'user', 'content': '你好', 'temperature': 0.7}

# 这会报错:ValidationError
# msg = ChatMessage(role="invalid", content="")

实战:异步批量调用LLM API

import asyncio
import httpx

async def call_llm(question):
    async with httpx.AsyncClient() as client:
        response = await client.post(
            "https://api.deepseek.com/v1/chat/completions",
            json={
                "model": "deepseek-chat",
                "messages": [{"role": "user", "content": question}]
            },
            headers={"Authorization": "Bearer YOUR_KEY"},
            timeout=30
        )
        return response.json()["choices"][0]["message"]["content"]

async def batch_ask(questions):
    tasks = [call_llm(q) for q in questions]
    return await asyncio.gather(*tasks)

# 5个问题并发请求,比串行快5倍
questions = ["Python是什么?", "FastAPI怎么用?", "RAG是什么?", "MCP是什么?", "Agent是什么?"]
# results = asyncio.run(batch_ask(questions))

总结

你已经会的(JS) 对应的Python 难度
Promise asyncio coroutine
async/await async def / await
Promise.all() asyncio.gather() ⭐⭐
PropTypes Pydantic BaseModel ⭐⭐
fetch() httpx.AsyncClient ⭐⭐

前端工程师学Python异步,就像换了一把长得差不多的剑——招式一样,只是手感略有不同。

更多推荐