python的Task等效于JS的promise.then()。catch()而不需要等待吗?

时间:2019-08-08 15:11:41

标签: python promise async-await python-asyncio coroutine

这为将来增加了成功/错误处理程序,例如:

async function send(item) {
    // ...
}

for (const item of items) {
    const sendPromise = send(item);
    sendPromise
        .then(x => console.log(x))
        .catch(x => console.error(x))
}

而不是像这样等待:

for (const item of items) {
    const sendPromise = send(item);
    try {
        const x = await sendPromise
        console.log(x)
    } catch (e) {
        console.error(e)
    }
}

没有wait的python任务相当于JS的promise.then()吗?

async def send(item):
    pass

for item of items:
    send_coro = send(item)
    send_task = asyncio.create_task(send_coro)
    # ?????
}

1 个答案:

答案 0 :(得分:1)

如果我正确阅读了JavaScript,它将在将来添加一个错误处理程序。直译可能类似于:

def _log_err(fut):
    if fut.exception() is not None:
        print(f'error: {fut.exception()}')

for item in items:
    send_future = asyncio.create_task(send(item))
    send_future.add_done_callback(_log_err)

请注意,以上内容并非惯用语,因为它诉诸回调,并且不如原始JavaScript(其中thencatch返回可以很好地链接的新期货)优雅。

更好的方法是使用辅助协程托管await。这不需要外部函数为async def,因此与上面的等效:

async def _log_err(aw):
    try:
        return await aw
    except Exception as e:
        print(f'error: {e}')

for item in items:
    asyncio.create_task(_log_err(send(item)))