从五年前的前端老代码中,学到的编码小技巧~

前言

大家好,我是林三心,用最通俗易懂的话讲最难的知识点是我的座右铭,基础是进阶的前提是我的初心。

背景

最近在看一个比较老的工具库源码,学到了一点代码的小技巧,我觉得对于以后的异步操作开发来说挺有用的,所以今天写了一篇文章,分享给大家~

例子

假设,现在有一个类,这个类维护了一个db对象,但是这个db对象需要通过异步操作(请求)并拿到结果,来进行初始化,且我们需要用到db对象上的get方法,来进行数据的获取,请看下方简易代码~

ts 复制代码
const request = () => {
  return new Promise(resolve => {
    // 模拟请求后得到db对象
    setTimeout(() => {
      resolve({
        get: key => key,
      });
    }, 300);
  });
};

class DB {
  private db;
  constructor() {
    this.init();
  }

  init() {
    return request().then(res => {
      this.db = res;
    });
  }

  getItem() {
    console.log(this.db.get('info'));
  }
}

接着我们进行实例的创建,并使用getItem方法去执行db对象身上的get方法,获取我们想要的数据,但是此时会引起报错,说db不存在

ts 复制代码
const base = new Base();
base.getItem(); // 报错:this.db 不存在

这是因为db是通过异步获取的,当你执行getItem的时候,db 还没初始化完成呢,所以我们得换一种写法我们需要保证init异步执行完成,再去执行后面的getItem,这样才不会报错

ts 复制代码
class Base {
  private db;

  init() {
    return request().then(res => {
      this.db = res;
    });
  }

  getItem() {
    console.log(this.db.get('info'));
  }
}

const fn = async () => {
  const base = new Base();
  await base.init();
  base.getItem(); // 'info'
};

改进

但是这样其实也不是好的做法,按理说init最好是不要去主动执行,而是应该写在内部,而且把异步init写在外面,又得套上async函数,非常麻烦,所以我们换一种写法。

大致思想就是,我们设置一个全局的promise,这个promise只有在初始化完成后,状态才会变成成功,才会执行 then 方法,然后对于 db 的操作,全都包裹在这个 promisethen 方法中,这样就能保证执行 db 身上方法时,db 已经被初始化完成了~

ts 复制代码
class Base {
  db;
  readyPromise;
  readyPromiseResolve;

  constructor() {
    this.init()
  }

  async init() {
    // 全局promise
    this.readyPromise = new Promise(resolve => {
      // 保存好全局resolve
      this.readyPromiseResolve = resolve
    })
    return request().then(res => {
      this.db = res;
      // 初始化完成后执行全局resolve
      this.readyPromiseResolve()
    });
  }

  ready() {
    // 获取全局promise
    return this.readyPromise
  }

  getItem() {
    // 全局promise执行then,说明已经初始化完成
    // 这时候执行 getItem 就不会报错了
    this.ready().then(() => {
      console.log(this.db.get('info'));
    })
  }
}

const base = new Base();
base.getItem() // 'info'

结语 & 加学习群 & 摸鱼群

我是林三心

  • 一个待过小型toG型外包公司、大型外包公司、小公司、潜力型创业公司、大公司的作死型前端选手;
  • 一个偏前端的全干工程师;
  • 一个不正经的掘金作者;
  • 一个逗比的B站up主;
  • 一个不帅的小红书博主;
  • 一个喜欢打铁的篮球菜鸟;
  • 一个喜欢历史的乏味少年;
  • 一个喜欢rap的五音不全弱鸡

如果你想一起学习前端,一起摸鱼,一起研究简历优化,一起研究面试进步,一起交流历史音乐篮球rap,可以来俺的摸鱼学习群哈哈,点这个,有7000多名前端小伙伴在等着一起学习哦 --> 摸鱼沸点

相关推荐
m0_528749004 分钟前
linux编程----目录流
java·前端·数据库
集成显卡4 分钟前
前端视频播放方案选型:主流 Web 播放器对比 + Vue3 实战
前端·vue·音视频
前端 贾公子4 分钟前
Vue3 业务组件库按需加载的实现原理(中)
前端·javascript·vue.js
温轻舟5 分钟前
前端可视化大屏【附源码】
前端·javascript·css·html·可视化·可视化大屏·温轻舟
北极象5 分钟前
Flying-Saucer HTML到PDF渲染引擎核心流程分析
前端·pdf·html
weixin199701080166 分钟前
Tume商品详情页前端性能优化实战
大数据·前端·java-rabbitmq
梦里寻码6 分钟前
深入解析 SmartChat 的 RAG 架构设计 — 如何用 pgvector + 本地嵌入打造企业级智能客服
前端·agent
edisao12 分钟前
第一章:L-704 的 0.00% 偏差
前端·数据库·人工智能
CappuccinoRose14 分钟前
HTML语法学习文档(一)
前端·学习·html
Cache技术分享17 分钟前
322. Java Stream API - 使用 Finisher 对 Collector 结果进行后处理
前端·后端