怎么处理异步操作
Handle asynchronous operations
一句话(按历史讲最清楚):回调 → Promise → async/await, 外加事件和 for await…of处理流式数据。
但这题真正的考点是 Promise 的四个静态方法怎么选, 一定会追问:
| 方法 | 什么时候 resolve | 用在哪 |
|---|---|---|
all | 全部成功才成功,一个失败立刻失败 | 几个都必须成功(页面必需的多个接口) |
allSettled | 全部结束就成功, 不管成败 | 批量操作,要知道每一个的结果 (批量上传,报告哪几个失败了) |
race | 第一个结束的说话, 成功失败都算 | 超时控制 |
any | 第一个成功的, 全失败才失败 | 多个镜像源取最快能用的那个 |
all 的坑: 它是 fail-fast 的 —— 一个失败,其他已经在飞的请求不会被取消, 而且你拿不到其他的结果。 「批量操作要逐个报告」的场景该用allSettled。
会追问:「怎么给一个请求加超时?」——Promise.race配一个定时 reject 的 Promise; 更好的是用 AbortController, 因为它能真的把请求掐掉,race 只是不等了。 这两个的区别在我们那道 fetch 变式题里也讲过。
In one line, and history tells it best: callbacks → Promises → async/await, plus events and for await…of for streaming data.
But what this question is really after is how you pick among the four static Promise methods, and they will ask:
| Method | When it resolves | Where you use it |
|---|---|---|
all | Succeeds only if all of them succeed, and fails the instant one fails | Everything must succeed (several calls the page needs) |
allSettled | Succeeds once everything has finished, win or lose | Bulk work where you need each result (a batch upload, reporting which ones failed) |
race | Whoever finishes first speaks, success or failure | Timeouts |
any | The first success; it fails only if all fail | Several mirrors, take the fastest one that works |
The trap in all: it is fail-fast — one rejection and the other requests already in flight are not cancelled, and you never see their results. When bulk work has to report item by item, reach for allSettled.
Follow-up: “How do you put a timeout on a request?” — Promise.race against a Promise that rejects on a timer. Better is AbortController, because it actually kills the request, whereas race merely stops waiting. We walk through that difference in the fetch variant question too.