在web?worker中使用fetch實(shí)例詳解
1.Web Worker意義
由于 JS 是單線程的,費(fèi)時(shí)的 JS 操作將會(huì)導(dǎo)致整個(gè)頁(yè)面的阻塞。Web Worker 提供了創(chuàng)建多線程的方法,將一些耗時(shí)且 UI 無(wú)關(guān)的工作交給 worker,可提高頁(yè)面的使用體驗(yàn)。
限制:
同源策略:worker 線程執(zhí)行的腳本要和當(dāng)前頁(yè)面同源
API 限制:
- 不能操作 DOM
- 不能使用 window 的全局變量,但可以使用 navigator 和 location 對(duì)象
- 不能使用 alert、confirm 方法
- 無(wú)法讀取本地文件
和主線程不在一個(gè)上下文環(huán)境,通訊要通過(guò) postMessage 完成
2. 主線程的使用
創(chuàng)建
創(chuàng)建一個(gè)子線程,要傳入一個(gè)腳本的 URL。如果該腳本加載失敗,則 Worker 會(huì)靜默失敗
const worker = new Worker('url');
如果要在本文件中描述執(zhí)行的內(nèi)容,可以用 Blob 和 window.URL.createObjectURL 生成一個(gè) URL
function createWorker(f) {
const blob = new Blob(['(' + f.toString() +')()']);
const url = window.URL.createObjectURL(blob);
const worker = new Worker(url);
return worker;
}
通信
- 主線程 => 子線程
worker.postMessage(param);
參數(shù)可以是任意類(lèi)型,包括二進(jìn)制數(shù)據(jù)。但傳遞是拷貝形式而不是引用形式。因此對(duì)于大數(shù)據(jù)會(huì)存在性能問(wèn)題。
- 子線程 => 主線程
worker.onmessage = function (event) {
console.log('Received message ' + event.data);
}
錯(cuò)誤處理
worker.onerror(function (e) {
console.log([
'ERROR: Line ', e.lineno, ' in ', e.filename, ': ', e.message
].join(''));
});
關(guān)閉
worker.terminate();
3. 子線程的使用
子線程中無(wú)法使用 window,self 代表全局對(duì)象
和主線程的通信
- 主線程 => 子線程
self.addEventListener('message', function (e) {
self.postMessage('Received: ' + e.data);
}, false);
- 子線程 => 主線程
self.postMessage('something');
加載其他腳本
在子線程中加載其他腳本:
importScripts('script1.js', 'script2.js');
關(guān)閉
self.close();
4. 在WebWorker中使用fetch
網(wǎng)絡(luò)請(qǐng)求是和DOM無(wú)關(guān)且可能耗時(shí)較長(zhǎng)的操作,worker線程支持使用Fetch,是適合放在worker中進(jìn)行的操作。
而要在worker中使用fetch,如果每次都要自己處理線程間的通信的話,會(huì)十分麻煩,因此我對(duì)通信進(jìn)行了封裝,寫(xiě)成了一個(gè)可以直接使用的庫(kù)。
安裝依賴(lài):
npm i web-worker-fetch
使用時(shí)先實(shí)例化一個(gè)WF對(duì)象,然后就可以像使用fetch一樣在worker中使用fetch:
import WebWorkerFetch from "web-worker-fetch";
const wf = new WebWorkerFetch();
wf.fetch("url", {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "cors", // no-cors, *cors, same-origin
cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json"
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: "follow", // manual, *follow, error
referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
}).then((res) => console.log(res));
除此之外,借鑒 axios 的思路,配置中可以提供 requestInterceptor 和 responseInterceptor,對(duì)請(qǐng)求參數(shù)和返回?cái)?shù)據(jù)做統(tǒng)一處理
5. 實(shí)現(xiàn)思路
這個(gè)庫(kù)的封裝主要是解決了兩個(gè)問(wèn)題:
- 發(fā)送請(qǐng)求時(shí)如何把參數(shù)傳遞給worker線程
- 請(qǐng)求結(jié)束后如何從worker線程獲取結(jié)果
對(duì)于第一個(gè)問(wèn)題,主線程使用 ostMessage 向worker線程傳遞參數(shù)。
對(duì)于第二個(gè)問(wèn)題,worker線程通過(guò) self.postMessage 向主線程傳遞消息,主線程通過(guò) worker.onmessage 監(jiān)聽(tīng)消息。
此時(shí)就引出了問(wèn)題所在:如果多次使用 wf.fetch 發(fā)送請(qǐng)求,那么在一個(gè)請(qǐng)求完成后,worker線程觸發(fā)的消息將讓所有請(qǐng)求處都認(rèn)為請(qǐng)求已完成。
因此,在每次請(qǐng)求時(shí),使用一個(gè)fetchId確定該請(qǐng)求做唯一性。將該id傳給worker線程,后續(xù)worker線程向主線程通信時(shí)也會(huì)帶上這個(gè)id。
在主線程中監(jiān)聽(tīng)onmessage事件時(shí),判斷id是否和自己的請(qǐng)求id一致,只有在相同時(shí)才做處理。
具體的實(shí)現(xiàn)大家可以移步倉(cāng)庫(kù)源碼,實(shí)際上也非常簡(jiǎn)單。
以上就是在web worker中使用fetch實(shí)例詳解的詳細(xì)內(nèi)容,更多關(guān)于web worker使用fetch的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JavaScript實(shí)現(xiàn)余額數(shù)字滾動(dòng)效果
這篇文章主要介紹了JavaScript實(shí)現(xiàn)余額數(shù)字滾動(dòng)效果,將傳入的帶滾動(dòng)的n位數(shù)字拆分成每一個(gè)要滾動(dòng)的數(shù),然后動(dòng)態(tài)的創(chuàng)建裝著滾動(dòng)到每一位相應(yīng)數(shù)字的容器,然后放入傳入的目標(biāo)容器中,更多詳細(xì)內(nèi)容,一起進(jìn)入下面文章學(xué)習(xí)吧2021-12-12
javascript Number 與 Math對(duì)象的介紹
這篇文章主要介紹了javascript Number 與 Math對(duì)象,文章圍繞 Number 與 Math對(duì)象的相關(guān)資料展開(kāi)內(nèi)容,需要的朋友可以參考一下,希望對(duì)你有所幫助2021-11-11
前端加密cryptojs與JSEncrypt使實(shí)例詳解
這篇文章主要為大家介紹了前端加密cryptojs與JSEncrypt使實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Promise靜態(tài)四兄弟實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了Promise靜態(tài)四兄弟實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
javascript 操作cookies詳解及實(shí)例
這篇文章主要介紹了javascript 操作cookies詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02

