写 Node 接口的时候,最开始啥也不懂,读个文件套个数据库查询再发个请求,三层回调嵌套下来代码就往右边飞了,缩进多到看不清哪个大括号是哪个的。后来被人安利了 Promise,再后来切到 async/await,世界终于清静了。这里记一下我在实际项目里踩过的坑和一些常用写法。
1. 先说说回调地狱有多恶心
大家应该都经历过这种代码:
1 | // 先登录,再拿用户信息,再拿订单列表…… |
每次写完这种东西,自己过两周再看都得愣半天。
2. Promise 基本用法
Promise 说白了就是把”以后才能拿到的东西”先用一个对象包起来,想用结果的时候用 .then() 去拿。
1 | // 封装一个请求 |
比回调好看多了,至少代码不会一直往右边缩进。
3. 我踩过的几个坑
坑一:.then() 里忘了 return
这个是新手最容易中招的,.then() 里面如果调了另一个异步操作但没 return,后面的 .then() 拿到的就是 undefined。
1 | // ❌ 错误写法 |
坑二:.catch() 的位置
.catch() 只能捕获它前面链条上的错误。如果 .catch() 后面还有 .then(),那个 .then() 还是会执行的。
1 | fetchUser(1) |
坑三:Promise.all 其中一个挂了全挂
并发请求的时候常用 Promise.all(),但只要有一个 reject,整个就进 catch 了,其他成功的结果也拿不到。
1 | // 三个请求只要挂一个,全部完蛋 |
如果你想”挂了也无所谓,能拿多少拿多少”,用 Promise.allSettled():
1 | Promise.allSettled([ |
4. async/await:写异步终于像写同步了
说实话我现在已经很少直接写 .then() 了,async/await 简直是解放双手。
1 | async function loadDashboard() { |
但要注意别犯一个低级错误——不必要的串行请求:
1 | // ❌ 这三个请求其实互不依赖,没必要一个等一个 |
5. 循环里用 await 要小心
在 for 循环里用 await 是没问题的,但在 forEach 里用就有坑了:
1 | // ❌ forEach 里的 await 不会等 |
这个坑我当时在处理批量上传文件的时候踩的,排查了好一会儿才发现是 forEach 的问题。
总的来说,日常写业务代码,基本就是 async/await + try/catch + Promise.all 这几板斧。够用了。
评论加载中…