代码优化及编程习惯

代码

避免 Promise.all 使用

  • Promise.all: 彼此相互依赖或者在其中任何一个reject时立即结束。
  • Promise.allSettled: 所有给定的 promise 都已经 fulfilled 或 rejected 后的 promise,并带有一个对象数组,每个对象表示对应的 promise 结果。

示例:

const promise1 = Promise.resolve(3);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'foo'));
const promises = [promise1, promise2];

Promise.allSettled(promises).
  then((results) => results.forEach((result) => console.log(result.status)));

// expected output:
// "fulfilled"
// "rejected"

目前大部分 Promise.all 使用的场景下,是多个任务并行执行,其中某个失败了也依然需要保证其他任务执行完毕。

p.s. 如果并发任务中有外部请求(如 HTTP Request、数据库查询连接创建等),不要用 Promise.allSettled, 而要自行封装 Promise.parallel 或者使用队列、Pooling(池)等方式去优化处理。

Async / Await 语法糖优化

// 没必要的 async / await
async function demo1(): Promise<any> {
  // 如果方法体内 没有 await 语法糖, 则不需要添加 async
  // 即便 return 方法为一个 Promise 返回值,也不需要添加 async
  return await someService.somePromiseFunction();
  // 如果方法体内 只在 return 部分有一个 await,建议优化掉, 去掉 await 和方法体上的 async
}

不要让 await 语句参与运算:

// Bad:
someArray.push(await someFunction());

const someObj = {
	result: await someFunction()
};


// Good:
const result = await someFunction();
someArray.push(result);

const result = await someFunction();
const someObj = {
	result
};

使用 RxJS 封装底层方法

学习教程: http://rx.js.cool/

贡献仓库: https://github.com/willin/rx.js.cool

适用场景介绍

前端组件
  • 如绑定鼠标移动事件并进行计算和处理
  • 如绑定鼠标点击事件并设置最小触发间隔
  • 侦听屏幕滚动并且 debounce
  • 等等

示例:

  • 解锁手势: https://stackblitz.com/edit/rxjs-lockscreen?file=index.ts
  • 扫雷游戏: https://stackblitz.com/edit/rxjs-minesweeper?file=index.ts
需要可撤销的业务场景

参考: http://rx.js.cool/mixin/undo

流式处理(流程化的方法)

示例:

from(Promise.resolve([
    // 模拟数据
    { id: 1, name: 'Kitty1', age: 1, breed: 'string' },
    { id: 2, name: 'Kitty2', age: 1, breed: 'string' },
    { id: 3, name: 'Kitty3', age: 1, breed: 'string' },
    { id: 4, name: 'Kitty4', age: 2, breed: 'string' },
    { id: 5, name: 'Kitty5', age: 2, breed: 'string' },
    { id: 6, name: 'Kitty6', age: 2, breed: 'string2' }
  ])).pipe(
    // 此处仅用于作为 rxjs 的操作示例
    // Filter by Age
    mergeMap((cats: Cat[]) =>
      iif(
        //
        () => age >= 0,
        // Query 里的数值类型,如果没有默认值,实际为字符串类型
        of(cats.filter((cat) => `${cat.age}` === `${age}`)),
        of(cats)
      )
    ),
    // Filter by Name
    mergeMap((cats: Cat[]) =>
      iif(
        //
        () => name !== '',
        of(cats.filter((cat) => cat.name === name)),
        of(cats)
      )
    ),
    // Filter by Breed
    mergeMap((cats: Cat[]) =>
      iif(
        //
        () => breed !== '',
        of(cats.filter((cat) => cat.breed === breed)),
        of(cats)
      )
    ),
    // Pagination
    mergeMap((cats: Cat[]) => of(cats.slice(offset, offset + limit)))
  );

Promise 方法改写

给出几种示例,更多需要自行摸索:

// 示例1:
import { from } from 'rxjs';

// getPromise() is called once, the promise is passed to the Observable
const observable$ = from(getPromise());

// 示例2:
import { defer } from 'rxjs';

// getPromise() is called every time someone subscribes to the observable$
const observable$ = defer(() => getPromise());
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Willin 老王带你躺平养老

感谢你这么好看还这么慷慨

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值