欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

以JS開(kāi)發(fā)為例詳解版本號(hào)的作用與價(jià)值

 更新時(shí)間:2023年09月14日 10:12:50   作者:jump__jump  
這篇文章主要為大家介紹了以JS開(kāi)發(fā)為例詳解版本號(hào)的作用與價(jià)值詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

導(dǎo)讀

在項(xiàng)目開(kāi)發(fā)和運(yùn)行的過(guò)程中,總是少不了各類(lèi)升級(jí)。例如某個(gè)功能組件需要更高的依賴(lài)庫(kù)、數(shù)據(jù)項(xiàng)需要進(jìn)行兼容等等問(wèn)題。遇到此類(lèi)問(wèn)題開(kāi)發(fā)者需要使用版本號(hào)來(lái)解決。今天我們就來(lái)分析一下項(xiàng)目迭代過(guò)程中會(huì)遇到的各類(lèi)升級(jí)問(wèn)題以及如何使用版本號(hào)來(lái)解決。

通常來(lái)說(shuō)升級(jí)會(huì)涉及到三個(gè)點(diǎn):

  • 向下兼容
  • 協(xié)商升級(jí)
  • 拒絕服務(wù)

依賴(lài)升級(jí)

開(kāi)發(fā)者在產(chǎn)品演進(jìn)的過(guò)程中會(huì)不斷的升級(jí)工具依賴(lài),以 npm 版本為例。版本號(hào)通常由三部分組成: 主版本號(hào)、次版本號(hào)和修訂版本號(hào)。

Major.Minor.Patch

其中,Major 表示主版本,當(dāng)你做了不兼容的 API 修改時(shí),就需要升級(jí)這個(gè)版本號(hào)。Minor 表示次版本,當(dāng)你做了向下兼容的功能性新增時(shí),就需要升級(jí)這個(gè)版本號(hào)。而 Patch 表示修訂版本,當(dāng)你做了向下兼容的問(wèn)題修正時(shí),就需要升級(jí)這個(gè)版本號(hào)。

每次在使用 npm install 時(shí)都會(huì)下載
package.json 中的依賴(lài)。而在在依賴(lài)中有 ^ 和 ~ 符號(hào)。其中 ^ 代表次版本兼容,~ 是修訂版本兼容。

{
  "devDependencies": {
    "lib1": "0.15.3",
    "lib2": "^0.15.3",
    "lib3": "~0.15.3"
  }
}

如果當(dāng)前三個(gè)庫(kù)都有幾個(gè)高版本,如:

  • 0.15.3
  • 0.15.4
  • 0.16.1
  • 1.0.0

在項(xiàng)目下載后執(zhí)行 install ,下載的對(duì)應(yīng)版本則是

  • lib1 0.15.3
  • lib2 0.16.1
  • lib3 0.15.4

雖然 ^ 和 ~ 都不會(huì)升級(jí)破壞性依賴(lài),但版本號(hào)只是“君子協(xié)議”。還是建議大家不要使用這些符號(hào)。同時(shí)之前也遇到過(guò)組件庫(kù)在某個(gè)修訂版本中出現(xiàn)了 bug。雖然很快修復(fù)好了。但是定位問(wèn)題還是需要花費(fèi)一定時(shí)間的。

數(shù)據(jù)緩存

很多情況,開(kāi)發(fā)者為了減少網(wǎng)絡(luò)請(qǐng)求都會(huì)使用數(shù)據(jù)緩存。如果是一個(gè)較為穩(wěn)定的數(shù)據(jù)。我們可以添加版本號(hào)進(jìn)行緩存(同時(shí)添加一個(gè)足夠長(zhǎng)的過(guò)期時(shí)間方便重新獲獲?。?。

以 localStorage 為例,代碼如下所示:

interface Store<T> {
  /** 存儲(chǔ)數(shù)據(jù) */
  data: T;
  /**
   * 當(dāng)前版本數(shù)據(jù),可以是一個(gè)數(shù)字或一個(gè)日期字符串 '220101-1'
   * 后續(xù)的 -1 是為了當(dāng)天發(fā)布多個(gè)版本而準(zhǔn)備的。
   */
  version: string | number;
  /**
   * 過(guò)期時(shí)間
   * 可以使用 時(shí)間戳(天數(shù)),天數(shù) dayjs 等
   */
  expries: string | number;
}
/**
  * 實(shí)際存儲(chǔ) key 值
  */
const XXX_STORAGE_KEY = 'storageKey';
const isNeedUpgrade = async <T>(): Promise<boolean> => {
  const storeJSONStr = localStorage.getItem(XXX_STORAGE_KEY);
  // 沒(méi)有存儲(chǔ) JSON 字符串
  if (storeJSONStr === null) {
    return true;
  }
  let store: Partial<Store<T>> = {};
  try {
    store = JSON.parse(storeJSONStr)
  } catch (e) {
    // JSON 字符串解析失敗
    return true;
  }
  const { expries, version: localVersion } = store;
  // 沒(méi)有過(guò)期時(shí)間獲取當(dāng)前時(shí)間超過(guò)過(guò)期時(shí)間
  if (!expries || isOverTime(expries)) {
    return true;
  }
  // 沒(méi)有緩存本地版本
  if (!localVersion) {
    return true;
  }
  const currentVersion = await getCurrentVersionForXXXStore();
  // 版本不一致
  if (currentVersion !== localVersion) {
    return true;
  }
  // 無(wú)需升級(jí)
  return false;
}

當(dāng)前代碼其實(shí)就涉及到了上述所說(shuō)的協(xié)商升級(jí)。

使用版本號(hào)進(jìn)行 api 維護(hù)

隨著業(yè)務(wù)的發(fā)展,數(shù)據(jù)結(jié)構(gòu)不可避免會(huì)發(fā)生一定的改變,如果僅僅只是增加一個(gè)數(shù)據(jù),開(kāi)發(fā)者可以直接在服務(wù)端做一下向下兼容即可。但有些時(shí)候我們可能需要做出一系列的調(diào)整,諸如前一個(gè)版本處理傳遞上來(lái)的 A 和 C 數(shù)據(jù),但是后一個(gè)版本需要處理 A 和 D 數(shù)據(jù)。這時(shí)候我們可能就無(wú)法通過(guò)數(shù)據(jù)傳輸來(lái)確定如何使用。因?yàn)槲覀儫o(wú)法保證服務(wù)端與客戶(hù)端能夠同步升級(jí)。

此時(shí)我們不得不借助版本號(hào)。新版本前端調(diào)用新版本的 API ,舊版本前端調(diào)用舊版本的 API。

/**
 * 2019-11-12 版本 15 兼容處理了 xxxx, xxxx
 * 2018-12-10 版本 14 xxxxxx
 */
const api = initRequest({
  // 全局 api 版本號(hào)
  apiVersion: 15,
});
const queryXXX = () => {
  return api({
    // 可以使用 api 版本號(hào),不傳遞默認(rèn)使用全局版本號(hào)
    apiVersion: 3,
  });
};

使用或者不使用全局版本號(hào)都有各自的優(yōu)點(diǎn)。使用全局版本號(hào)一個(gè)版本可以同時(shí)進(jìn)行多處修改,方便開(kāi)發(fā)者維護(hù)。但是如果 api 兼容過(guò)多的話(huà),apiVersion 也會(huì)升級(jí)的很快。最終反而不利于維護(hù)。大家可以酌情處理,如果是互聯(lián)網(wǎng)項(xiàng)目,大家可以考慮使用 api 獨(dú)立版本號(hào),如果是企業(yè)服務(wù)則優(yōu)先使用全局版本號(hào)。

大部分情況下服務(wù)端都可以兼容之前的代碼。

@Controller({
  path: "user",
  version: "2",
})
export class UserController {
  @Get()
  @Version("2")
  findAll() {
    return this.userService.findAll();
  }
  @Get()
  @Version("1")
  findAllOld() {
    return this.userService.findAllOld();
  }
}

極少數(shù)情況下,服務(wù)端代碼難以兼容,或者需要付出極大代價(jià),這時(shí)候就可以拒絕服務(wù)。

@Controller({
  path: "user",
  version: "2",
})
export class UserController {
  @Get()
  @Version("1")
  findAllOld() {
    // 拋出版本不支持異常
    throw BusinessException.throwVersionNotSupport();
  }
}

老的前端代碼中后端拒絕服務(wù)。這樣的話(huà)就不需要在服務(wù)端維護(hù)多個(gè)版本。代碼如下所示:

export const handleVersionError(err) {
  // 版本不支持和
  if (err.errCode !== 'versionNotSupport') {
    return;
  }
  this.$confirm('當(dāng)前版本過(guò)低,無(wú)法正常使用此功能。', '溫馨提示', {
    confirmButtonText: '刷新頁(yè)面使用最新版本',
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    location.reload();
  })
}

如果使用小程序開(kāi)發(fā),也可以通過(guò)小程序 API updateManager 重啟升級(jí)。代碼如下所示:

const updateManager = Taro.getUpdateManager();
updateManager.onCheckForUpdate(function (res) {
  // 請(qǐng)求完新版本信息的回調(diào)
  console.log(res.hasUpdate);
});
updateManager.onUpdateReady(function () {
  Taro.showModal({
    title: "更新提示",
    content: "新版本已經(jīng)準(zhǔn)備好,是否重啟應(yīng)用?",
    success: function (res) {
      if (res.confirm) {
        // 新的版本已經(jīng)下載好,調(diào)用 applyUpdate 應(yīng)用新版本并重啟
        updateManager.applyUpdate();
      }
    },
  });
});
updateManager.onUpdateFailed(function () {
  // 新的版本下載失敗
});

當(dāng)然,針對(duì)小程序開(kāi)發(fā)者還可以存儲(chǔ)當(dāng)前頁(yè)面和獲取信息,如果重啟小程序后,直接打開(kāi)對(duì)應(yīng)界面并刪除信息(添加超時(shí)機(jī)制)。

樂(lè)觀鎖

樂(lè)觀鎖也是利用了版本號(hào)來(lái)實(shí)現(xiàn)的。

當(dāng)一些可變數(shù)據(jù)無(wú)法隔離時(shí)候,開(kāi)發(fā)者可以用兩種不同的控制策略:樂(lè)觀鎖策略和悲觀鎖策略。樂(lè)觀鎖用于沖突檢測(cè),悲觀鎖用于沖突避免。

悲觀者策略非常簡(jiǎn)單,當(dāng) A 用戶(hù)獲取到用戶(hù)信息時(shí)系統(tǒng)把當(dāng)前用戶(hù)信息給鎖定,然后 B 用戶(hù)在獲取用戶(hù)信息時(shí)就會(huì)被告知?jiǎng)e人正在編輯。等到 A 員工進(jìn)行了提交,系統(tǒng)才允許 B 員工獲取數(shù)據(jù)。此時(shí) B 獲取的是 A 更新后的數(shù)據(jù)。

樂(lè)觀者策略則不對(duì)獲取進(jìn)行任何限制,它可以在用戶(hù)信息中添加版本號(hào)來(lái)告知用戶(hù)信息已被修改。樂(lè)觀鎖要求每條數(shù)據(jù)都有一個(gè)版本號(hào),同時(shí)在更新數(shù)據(jù)時(shí)候就會(huì)更新版本號(hào),如 A 員工在更新用戶(hù)信息時(shí)候提交了當(dāng)前的版本號(hào)。系統(tǒng)判斷 A 提交的時(shí)候的版本號(hào)和該條信息版本號(hào)一致,允許更新。然后系統(tǒng)就會(huì)把版本號(hào)修改為新的版本號(hào),B 員工來(lái)進(jìn)行提交時(shí)攜帶的是之前版本號(hào),此時(shí)系統(tǒng)判定失敗。

業(yè)務(wù)也可以根據(jù)情況添加用戶(hù)問(wèn)詢(xún),詢(xún)問(wèn)用戶(hù)是否需要強(qiáng)制更新,在用戶(hù)選擇“是”時(shí)可以添加額外參數(shù)并攜帶之前的版本號(hào)以方便日志信息存儲(chǔ)。

當(dāng)然了,如果當(dāng)前業(yè)務(wù)對(duì)時(shí)間要求沒(méi)有那么高的情況下,開(kāi)發(fā)者也可以直接利用數(shù)據(jù)的更新時(shí)間作為這條數(shù)據(jù)的版本號(hào)。

以上就是以JS開(kāi)發(fā)為例詳解版本號(hào)的作用與價(jià)值的詳細(xì)內(nèi)容,更多關(guān)于JS開(kāi)發(fā)版本號(hào)作用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論