使用「設(shè)計(jì)模式」巧妙解決 BUG 的經(jīng)歷,妙啊~
是這樣的,這天,我接到了一個(gè) BUG,當(dāng)然這個(gè) BUG 不是我寫的,是這樣的有兩個(gè)頁面:
- 頁面 A:有同步代碼,有異步代碼
 - 頁面 B:全是同步代碼
 

注意:此項(xiàng)目是老項(xiàng)目,沒有全局狀態(tài)管理工具!??!
// 頁面A
console.log(1)
console.log(2)
http.get(url).then(res => {
  console.log(3)
  localStorage.setItem(key, res)
})
// 頁面B
console.log(
  localStorage.getItem(key)
)然后這兩個(gè)頁面是先后加載的,那么我們可以得出輸出順序是:
1 // 頁面A
2 // 頁面A
undefined // 頁面B
console.log(3) // 頁面A因?yàn)檎?qǐng)求是異步的,導(dǎo)致頁面B那邊拿不到 localStorage 里面的東西,而無法完成很多操作,導(dǎo)致了出現(xiàn) BUG。所以得想想怎么去解決這個(gè) BUG。
定時(shí)器
最簡(jiǎn)單的就是利用定時(shí)器去解決:
// 頁面B
setTimeout(() => {
  console.log(
  localStorage.getItem(key)
  )
})但是這樣是不對(duì)的,不好維護(hù),濫用定時(shí)器會(huì)導(dǎo)致以后可能會(huì)有新的 BUG 出現(xiàn)?。?!
發(fā)布訂閱模式
所以還是使用發(fā)布訂閱,首先實(shí)現(xiàn)一個(gè)發(fā)布訂閱中心,以下是簡(jiǎn)單實(shí)現(xiàn):
type Callback<T> = (data: T) => void;
class PubSub<T> {
  private subscribers: Callback<T>[] = [];
  subscribe(callback: Callback<T>): void {
    this.subscribers.push(callback);
  }
  unsubscribe(callback: Callback<T>): void {
    this.subscribers = this.subscribers.filter(fn => fn !== callback);
  }
  publish(data: T): void {
    this.subscribers.forEach(fn => fn(data));
  }
}
export const ps = new PubSub();接著就可以用它來解決我們那個(gè) BUG 了??!
// 頁面A
console.log(1)
console.log(2)
http.get(url).then(res => {
  console.log(3)
  localStorage.setItem(key, res)
  ps.publish(res)
})
// 頁面B
// 訂閱
ps.subscribe((res) => {
  console.log(res)
  console.log(
    localStorage.getItem(key)
  )
})現(xiàn)在的輸出順序就是:
1 // 頁面A
2 // 頁面A
console.log(3) // 頁面A
res // 頁面B
res // 頁面B小結(jié)
這就是利用了 發(fā)布訂閱模式 這種設(shè)計(jì)模式,來解決我們?nèi)粘5囊恍┖?jiǎn)單業(yè)務(wù),所以大家可以多用,這樣在面試時(shí)就不怕面試官問你啦!















 
 
 









 
 
 
 