异步
类型会标了,看异步怎么跑。先入口,再迭代,再并发。
async / await / asyncio.run
python
async def async_main() -> None:
await execution.async_start(payload)
await execution.async_close()
def main() -> None:
asyncio.run(async_main())js
async function asyncMain() {
await execution.asyncStart(payload)
await execution.asyncClose()
}
await asyncMain()Python 文件顶层一般不能直接 await,要用 asyncio.run(...) 包一层。Node 顶层可以 await。
默认参数也可以塞异步函数引用:
python
async def run(extractor: SegmentExtractor = extract_segment_from_reference):
...js
async function run(extractor = extractSegmentFromReference) {
...
}async for
python
async for item in result.get_async_generator(type="instant"):
if not item.is_complete:
continue
await emit_action_ready(...)js
for await (const item of asyncGenerator) {
if (!item.is_complete) continue
await emitActionReady(...)
}| Python | JavaScript |
|---|---|
async for x in agen: | for await (const x of agen) |
asyncio.sleep(秒) | setTimeout 包成 Promise(毫秒) |
python
await asyncio.sleep(0.01)js
await new Promise((r) => setTimeout(r, 10))create_task:先跑、稍后再等
python
close_task = asyncio.create_task(execution.async_close())
async for item in execution.get_async_runtime_stream(timeout=None):
items.append(item)
state = await close_taskjs
const closePromise = execution.asyncClose()
for await (const item of execution.getAsyncRuntimeStream()) {
items.push(item)
}
const state = await closePromise模式:关执行和读流重叠进行。create_task(coro) ≈ 先拿到 Promise,稍后再 await。
gather:一起等完
asyncio.gather(*tasks) 把一堆协程同时跑,全部结束后才往下。* 把列表拆开传进去。
python
tasks = [_run(item) for item in items]
await asyncio.gather(*tasks)js
const tasks = items.map((item) => run(item))
await Promise.all(tasks)| Python | JavaScript |
|---|---|
asyncio.gather(*tasks) | Promise.all(tasks) |
| 默认一个失败就取消其余 | Promise.all 同样:一个 reject 就整组失败 |
只要「谁先好谁先用」用 create_task;要「这批全好再继续」用 gather。
async with + Semaphore
async with 是异步版 with:进入时获取,离开时释放。常和 Semaphore 限并发。
python
semaphore = asyncio.Semaphore(bounded)
async def _run(item):
async with semaphore:
by_id[item.item_id] = await summarize(item)
await asyncio.gather(*[_run(item) for item in items])js
await Promise.all(
items.map(async (item) => {
await limit.acquire()
try {
byId[item.item_id] = await summarize(item)
} finally {
limit.release()
}
}),
)JS 没有 async with。对等写法是 try/finally 里释放;限流要自己数,或用现成池(如 p-limit)。
yield:异步生成器
async def 里 yield 就变成异步生成器,外面用 async for 逐个拿。
python
async def iter_messages(queue):
try:
while True:
yield await queue.get()
finally:
cleanup()js
async function* iterMessages(queue) {
try {
while (true) {
yield await queue.get()
}
} finally {
cleanup()
}
}| Python | JavaScript |
|---|---|
async def + yield | async function* + yield |
外面 async for x in agen | for await (const x of agen) |
调用方 break / aclose() | 迭代器 return(),会走 finally |
同步版是普通 def + yield,外面用普通 for。这里课程里常见的是异步那条。
下一页是最后一层:闭包工厂、装饰器、命令行、图状态类型。