成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

記錄第一次給開(kāi)源項(xiàng)目提 PR

開(kāi)源
本篇文章算是該系列的一個(gè)彩蛋篇,記錄一下第一次給開(kāi)源項(xiàng)目提 PR 的過(guò)程(之前好像也有過(guò),不過(guò)那個(gè)非常小的一個(gè)改動(dòng)),希望能夠幫助更多的人參與到開(kāi)源項(xiàng)目中來(lái)。

注:本系列對(duì) ahooks 的源碼解析是基于 v3.3.13。自己 folk 了一份源碼,主要是對(duì)源碼做了一些解讀,可見(jiàn) 詳情[1]。

本篇文章算是該系列的一個(gè)彩蛋篇,記錄一下第一次給開(kāi)源項(xiàng)目提 PR 的過(guò)程(之前好像也有過(guò),不過(guò)那個(gè)非常小的一個(gè)改動(dòng)),希望能夠幫助更多的人參與到開(kāi)源項(xiàng)目中來(lái)。

起因

在寫(xiě)了幾篇關(guān)于 ahooks 的文章之后,收到了官方同學(xué)的私信。

圖片

這讓我受寵若驚的同時(shí)也有點(diǎn)小興奮和惶恐。

興奮是,之前感覺(jué)參與開(kāi)源是一件遙不可及的事情,現(xiàn)在似乎我也能夠去做了。當(dāng)然也有私心,假如我的簡(jiǎn)歷上有給開(kāi)源項(xiàng)目做貢獻(xiàn)的經(jīng)歷,那豈不是一個(gè)不錯(cuò)的加分項(xiàng)?

惶恐的是,我之前沒(méi)有參與過(guò)開(kāi)源項(xiàng)目,擔(dān)心自己不能做好這件事。

根據(jù)大佬的建議,我決定先從一些 issue 入手,也就是幫忙解決一下 issue。

明確問(wèn)題OR需求

于是我抱著試試看的態(tài)度,看了一下官方的 issue,看到這么一條。issue 詳情[2]

圖片

剛好我之前對(duì) useRequest 源碼做過(guò)一些分析——如何使用插件化機(jī)制優(yōu)雅的封裝你的請(qǐng)求[3]。于是我決定 fix 一下這個(gè) issue。

這個(gè) issue 的需求很簡(jiǎn)單,就是希望輪詢失敗后,能夠支持最大的輪詢次數(shù),假如失敗的次數(shù)大于這個(gè)值,則停止輪詢。

編碼前準(zhǔn)備

首先,從 ahooks 官方 GitHub 中 folk 一份。這個(gè)操作我之前已經(jīng)做了。

圖片

第二步,基于 master 切換一個(gè)功能分支。如下:

git checkout -b fix/pollingSupportRetryCount

最后就是環(huán)境的一些初始化操作,不同的倉(cāng)庫(kù)不同,ahooks 如下:

yarn run init
yarn start

功能實(shí)現(xiàn)

我們先來(lái)看下現(xiàn)在 useRequest 的輪詢的實(shí)現(xiàn),其原理主要是在一個(gè)請(qǐng)求結(jié)束的時(shí)候(不管成功與失敗),通過(guò) setTimeout 進(jìn)行重新請(qǐng)求,達(dá)到輪詢的效果。

onFinally: () => {
// 省略部分代碼...
// 通過(guò) setTimeout 進(jìn)行輪詢
timerRef.current = setTimeout(() => {
fetchInstance.refresh();
}, pollingInterval);
},

我的想法是,定義一個(gè) options 參數(shù),pollingErrorRetryCount,默認(rèn)為 -1,代表沒(méi)有限制。

另外定義一個(gè)變量,記錄當(dāng)前重試的次數(shù):

const countRef = useRef<number>(0);

當(dāng)開(kāi)發(fā)者設(shè)置了 pollingErrorRetryCount,并且重試的數(shù)量大于該值,我們就直接返回,不執(zhí)行輪詢的邏輯。

當(dāng)成功或者失敗的時(shí)候,更新當(dāng)前重試的次數(shù):

onError: () => {
countRef.current += 1;
},
onSuccess: () => {
countRef.current = 0;
},

然后在請(qǐng)求結(jié)束的時(shí)候,判斷重試的次數(shù)有沒(méi)有達(dá)到了開(kāi)發(fā)設(shè)置的次數(shù),假如沒(méi)有則執(zhí)行重試操作。有則重置重試的次數(shù),停止輪詢。

onFinally: () => {
if (
pollingErrorRetryCount === -1 ||
// When an error occurs, the request is not repeated after pollingErrorRetryCount retries
(pollingErrorRetryCount !== -1 && countRef.current <= pollingErrorRetryCount)
) {
// 忽略部分代碼
timerRef.current = setTimeout(() => {
fetchInstance.refresh();
}, pollingInterval);
} else {
countRef.current = 0;
}
},

測(cè)試用例

上述整體的改造并不困難,但是我在寫(xiě)測(cè)試用例的時(shí)候,就開(kāi)始踩坑了,因?yàn)槲液苌贂?shū)寫(xiě)前端的測(cè)試用例,還是針對(duì)于 hooks 的測(cè)試用例。這里是我耗時(shí)最多的地方。

最終用例如下:

// 省略部分代碼...
// if request error and set pollingErrorRetryCount
// and the number of consecutive failures exceeds pollingErrorRetryCount, polling stops
let hook2;
let errorCallback;
act(() => {
errorCallback = jest.fn();
hook2 = setUp(() => request(0), {
pollingErrorRetryCount: 3,
pollingInterval: 100,
pollingWhenHidden: true,
onError: errorCallback,
});
});
expect(hook2.result.current.loading).toEqual(true);
expect(errorCallback).toHaveBeenCalledTimes(0);
act(() => {
jest.runAllTimers();
});
await hook2.waitForNextUpdate();
expect(hook2.result.current.loading).toEqual(false);
expect(errorCallback).toHaveBeenCalledTimes(1);
act(() => {
jest.runAllTimers();
});
await hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(2);
act(() => {
jest.runAllTimers();
});
await hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(3);
act(() => {
jest.runAllTimers();
});
await hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(4);
act(() => {
jest.runAllTimers();
});
expect(errorCallback).toHaveBeenCalledTimes(4);
act(() => {
hook2.result.current.run();
});
act(() => {
jest.runAllTimers();
});
await hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(5);
hook2.unmount();
// 省略部分代碼...

大致解釋下該測(cè)試用例的邏輯,我設(shè)置了重試三次,錯(cuò)誤之后,運(yùn)行了三次,errorCallback 就會(huì)被調(diào)用了 4 次(包括錯(cuò)誤那次)。在第五次執(zhí)行的時(shí)候,就不會(huì)執(zhí)行 errorCallback,也就還是 4 次。然后我們手動(dòng) run 一次請(qǐng)求,期待 errorCallback 應(yīng)該執(zhí)行 5 次。

這里踩了一個(gè)坑,就是第五次請(qǐng)求的時(shí)候,我之前是會(huì)寫(xiě)一個(gè)等待定時(shí)器執(zhí)行的操作,但實(shí)際上這里它是不會(huì)執(zhí)行定時(shí)器的,導(dǎo)致一直報(bào)錯(cuò),在這里折騰了很久。后來(lái)刪除了下面的代碼才執(zhí)行成功。

act(() => {
jest.runAllTimers();
});
- await hook2.waitForNextUpdate();
expect(errorCallback).toHaveBeenCalledTimes(4);

文檔以及 Demo 補(bǔ)充

畢竟加了一個(gè)新的 API 參數(shù),需要在文檔中注明,而且中英文文檔都需要補(bǔ)充,還加上了一個(gè) Demo 示例。

圖片圖片

提 PR

上述都完成之后,就可以提交你的代碼了,提交完,去到在你 folk 過(guò)來(lái)的項(xiàng)目中,可以看到這個(gè)。

圖片

我們需要點(diǎn)擊圖中框起來(lái)的「Compare & pull request 」,之后就會(huì)出現(xiàn)如下圖

圖片

默認(rèn)會(huì)幫我們選好分支的,我們只需要完善其中的信息,還有我們之前提交的 message 也可以修改。最好可以用英文來(lái)解釋,本次提交的內(nèi)容。

最后點(diǎn)擊提交之后就好了。

還有一個(gè)提 PR 的入口,如下所示:

圖片圖片

最后等待官方 CR 就可以了(上面的實(shí)現(xiàn)其實(shí)部分是 CR 后改的)。目前該 PR 已經(jīng)被合入到 master。

總結(jié)思考

給開(kāi)源項(xiàng)目提 PR 操作過(guò)程不是一件很復(fù)雜的事情,重點(diǎn)在于需求的修改。往往需要考慮到多種邊界場(chǎng)景,這個(gè)時(shí)候,我們就需要前端的單元測(cè)試來(lái)幫助我們覆蓋全面的場(chǎng)景。

另外,對(duì)于一些還沒(méi)有參與開(kāi)源項(xiàng)目經(jīng)驗(yàn)的同學(xué)來(lái)講,我覺(jué)得類似 ahooks 這種工具庫(kù)是一個(gè)不錯(cuò)的選擇:

  • 它的模塊劃分更加清晰,你改了一個(gè)模塊的功能,影響面可以更好的預(yù)估。對(duì)新人比較友好。
  • 邏輯相對(duì)簡(jiǎn)單,其實(shí)你會(huì)發(fā)現(xiàn)很多代碼說(shuō)不定在你們的業(yè)務(wù)項(xiàng)目中的 utils/hooks 文件夾中就有。
  • 社區(qū)比較活躍,維護(hù)者能夠較快的響應(yīng)。

希望對(duì)大家有所幫助。

參考資料

[1]詳情: https://github.com/GpingFeng/hooks。

[2]issue 詳情: https://github.com/alibaba/hooks/issues/1645。

[3]如何使用插件化機(jī)制優(yōu)雅的封裝你的請(qǐng)求: https://juejin.cn/post/7105733829972721677。

責(zé)任編輯:姜華 來(lái)源: 前端雜貨鋪
相關(guān)推薦

2011-07-21 21:01:37

諾基亞塞班蘋(píng)果

2017-03-22 15:38:28

代碼架構(gòu)Java

2023-09-11 00:14:46

后端團(tuán)隊(duì)項(xiàng)目

2015-08-17 10:10:10

創(chuàng)業(yè)失敗經(jīng)驗(yàn)

2014-05-19 10:16:56

WinJS開(kāi)源TypeScript

2022-08-15 08:16:56

shiroWeb認(rèn)證

2022-03-16 14:59:28

打包debian模板文件

2012-04-13 10:11:58

Windows 8泄露

2021-08-05 08:18:02

開(kāi)源項(xiàng)目 PR

2015-10-26 16:38:17

2021-02-05 08:35:21

私活程序員

2016-07-14 14:07:04

云計(jì)算OpenStack

2012-01-18 11:18:12

Web App

2013-02-25 09:43:22

LambdasJava8

2018-11-21 14:51:00

Windows 功能系統(tǒng)

2018-08-15 10:34:30

戴爾

2017-08-08 12:50:51

Serverless云端數(shù)據(jù)庫(kù)

2015-11-02 14:42:12

2018-09-11 17:05:12

戴爾

2013-05-13 11:35:53

獨(dú)立開(kāi)發(fā)開(kāi)發(fā)經(jīng)驗(yàn)開(kāi)發(fā)感悟
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 2018国产大陆天天弄 | 羞羞视频在线观看 | 日韩欧美亚洲 | www四虎影视 | 超碰成人免费观看 | 亚洲视频在线免费观看 | 国产免费观看一级国产 | 成人精品一区二区户外勾搭野战 | 国产一级淫片a直接免费看 免费a网站 | 国产精品久久久久久久一区二区 | 九九天堂网 | 久久黄色精品视频 | 国产99免费| 久久精品日产第一区二区三区 | 日韩欧美1区2区 | 国产精品国产 | 狠狠躁躁夜夜躁波多野结依 | 精品美女视频在线观看免费软件 | 日韩免费网站 | 中文字幕乱码视频32 | 国产精品成人一区二区 | 日韩精品 电影一区 亚洲 | 免费一级片| 99pao成人国产永久免费视频 | 日日骚视频 | 欧美13videosex性极品 | 日韩欧美中文 | 亚洲精品久久久久久久久久吃药 | 国产丝袜一区二区三区免费视频 | 国产98色在线 | 日韩 | 欧美激情国产日韩精品一区18 | 91在线视频网址 | a免费在线| 91精品久久久| 99精品国自产在线 | 精品伊人久久 | 免费在线成人网 | 亚洲国产欧美91 | 久久99精品久久久久久噜噜 | 婷婷综合色 | 五月天天丁香婷婷在线中 |