摘要:什么是最大安全整數(shù)是一個(gè)值為的常量。因?yàn)榈臄?shù)字存儲(chǔ)使用了中規(guī)定的雙精度浮點(diǎn)數(shù)數(shù)據(jù)類型,而這一數(shù)據(jù)類型能夠安全存儲(chǔ)到之間的數(shù)值包含邊界值。
什么是最大安全整數(shù)?
MAX_SAFE_INTEGER 是一個(gè)值為 9007199254740991的常量。因?yàn)镴avascript的數(shù)字存儲(chǔ)使用了IEEE 754中規(guī)定的雙精度浮點(diǎn)數(shù)數(shù)據(jù)類型,而這一數(shù)據(jù)類型能夠安全存儲(chǔ) -(253 - 1) 到 253 - 1 之間的數(shù)值(包含邊界值)。--- MDN WEB DOCS在項(xiàng)目會(huì)導(dǎo)致什么錯(cuò)誤?
在代碼中輸出比MAX_SAFE_INTEGER大的Number值
console.log(9007199254740999) // 9007199254741000 console.log(9007199254740993) // 9007199254740992
在代碼中比較超出安全存儲(chǔ)的數(shù)值,可能會(huì)存在下列情況
9007199254740993 === 9007199254740992 // true實(shí)際項(xiàng)目中碰到的問題
在進(jìn)行vue 項(xiàng)目開發(fā)的時(shí)候,通過axios進(jìn)行前后端數(shù)據(jù)交互
后端在定義某些數(shù)據(jù)時(shí)將數(shù)據(jù)的ID 設(shè)置為比MAX_SAFE_INTEGER大的int類型
而我取到后也沒有注意到這一情況,在修改某一條數(shù)據(jù)時(shí),是通過傳回?cái)?shù)據(jù)ID進(jìn)行數(shù)據(jù)定位的。
然后問題就出現(xiàn)了。。。。
數(shù)據(jù)死活修改不了,后端返回?zé)o這條數(shù)據(jù),調(diào)試了半天,
然后通過對(duì)比preview 和 response 中的數(shù)據(jù)發(fā)現(xiàn)了兩者數(shù)據(jù)不一致
如何解決?第一個(gè)想法是在axios的攔截器中做處理,將數(shù)字類型轉(zhuǎn)換為字符串
9007199254740993 => "9007199254740993"
但經(jīng)過嘗試后發(fā)現(xiàn)axios攔截器中的數(shù)據(jù)本身就是錯(cuò)誤了。
然后就用了原生的fetch 做處理
export function getData(data) { const promise = new Promise(function (resolve, reject) { const headers = new Headers() headers.append("Content-Type", "application/json") const config = { method: "POST", headers, body: JSON.stringify(data) } fetch("api/url", config).then(res => res.text()).then(text => { function numberToString (match) { return `:"${match.substring(1, match.length - 1)}",` } const responseJson = JSON.parse(text.replace(/:d{15,100},/g, numberToString)) resolve(responseJson) }) }) return promise }
但問題是這個(gè)只解決了一個(gè)api 的問題,然后每個(gè)都這樣寫,太煩了。
而且fetch 并沒有axios中的攔截器,不能統(tǒng)一處理異常
所有便想要自己封裝一個(gè)fetch通過模仿axios 那樣設(shè)置攔截器之類的功能。。。。。。
然后就沒有然后了,感覺封裝一個(gè)目前需要的fetch會(huì)花個(gè)半天到一天的時(shí)間。
而且又快下班了,所以就去看axios文檔了。
發(fā)現(xiàn)axios文檔中已經(jīng)有這樣一個(gè)回調(diào)函數(shù),能解決這個(gè)問題
// `transformResponse` allows changes to the response data to be made before // it is passed to then/catch transformResponse: [function (data) { // Do whatever you want to transform the data return data; }],
這個(gè)不看文檔的壞習(xí)慣,浪費(fèi)了大半天時(shí)間
最后代碼
const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url timeout: 5*1000, // request timeout transformResponse: [function (data) { function numberToString (match) { return `:"${match.substring(1, match.length - 1)}",` } if (isJSON(data)) { const responseJson = JSON.parse(data.replace(/:d{15,100},/g, numberToString)) return responseJson } else { return data } }] })總結(jié)
第一,我這個(gè)數(shù)據(jù)是json類型的的所以在取到原始數(shù)據(jù)就是字符串,其實(shí)是對(duì)字符串進(jìn)行處理
第二,最后的方案不是最優(yōu)的,應(yīng)為這個(gè)會(huì)處理每一條數(shù)據(jù),不管那條數(shù)據(jù)中有沒有超出范圍的數(shù)字
第三,能想到的比較好的方案是和后端對(duì)接時(shí)問清楚那些是超出的,然后將這兩種情況區(qū)分開來,再使用不同的axios 封裝
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/109893.html