AJAX、axios、fetch的區(qū)別
AJAX
Gmail開發(fā)人員發(fā)現(xiàn)IE里面有個XMLHTTPRequest
對象來請求數(shù)據(jù)時,可以實現(xiàn)無刷新數(shù)據(jù)請求,所以使用這個特性,進行網(wǎng)絡數(shù)據(jù)請求,這就是AJAX
的由來。AJAX
不是一個單詞,他的全稱是Asynchronous JavaScript and XML
,就是異步的JavaScript
和XML
,它是一套用于創(chuàng)建快速動態(tài)網(wǎng)頁的技術(shù)標準,使用步驟如下:
創(chuàng)建異步XMLHttpRequest
對象
設(shè)置請求參數(shù),包括請求的方法和URL等
發(fā)送請求
注冊事件,事件狀態(tài)變更會及時響應監(jiān)聽
在監(jiān)聽里面獲取并處理返回數(shù)據(jù)
所以AJAX
的核心就是XMLHttpRequest
對象,這是一個非常早的實現(xiàn)方法,也是兼容性最好的,已經(jīng)成為了瀏覽器標準,雖然我們現(xiàn)在都使用其它的API規(guī)范,但對象名字暫時還是用XML
命名
axios
axios
是一個基于Promise
的HTTP
庫,可以用在瀏覽器和node.js
中,它底層還是基于XMLHttpRequest
對象的,你可以認為它是一個方便的封裝庫,除了基礎(chǔ)請求數(shù)據(jù),它還增加了如下功能:
對PromiseAPI
的支持
支持請求攔截和響應、轉(zhuǎn)換請求數(shù)據(jù)和響應數(shù)據(jù)、取消請求
可以自動轉(zhuǎn)換JSON
數(shù)據(jù)
支持防御XSRF
fetch
fetch
就不是XMLHttpRequest
對象了,fetch
是原生的js對象,是ES6新增的通信方法。也就是說,它不依賴瀏覽器,fetch
提供了一個理解的請求替換方案,可以提供給其它技術(shù)使用。我們主要需要了解下fetch
和ajax
的本質(zhì)區(qū)別:
fetch
返回的是Promise
,所以如果HTTP狀態(tài)碼是404之類的,fetch也是成功返回的,只有在網(wǎng)絡連接錯誤的情況下,才會reject
fetch
不發(fā)送cookies
fetch
的請求寫法會比AJAX
簡單許多,但我想,最主要的問題是,無法區(qū)分HTTP狀態(tài)碼了,這個在編程時還是比較常用的,所以我們目前還是使用axios
比較多,而很少使用fetch
文章來源:http://www.zghlxwxcb.cn/news/detail-610527.html
實現(xiàn)
為什么?
我們現(xiàn)在都是單頁面應用,需要做并發(fā)限制文章來源地址http://www.zghlxwxcb.cn/news/detail-610527.html
串行和并行
- 串行:請求是異步的,需要等待上一個請求成功,才能執(zhí)行下一個請求
- 并行:同時發(fā)送多個請求「HTTP請求可以同時進行,但是JS的操作都是一步步的來的,因為JS是單線程」,等待所有請求都成功,我們再去做什么事情?
Promise.all并發(fā)限制及async-pool的應用
const delay = function delay(interval) {
return new Promise((resolve, reject) => {
setTimeout(() => {
// if (interval === 1003) reject('xxx');
resolve(interval);
}, interval);
});
};
let tasks = [() => {
return delay(1000);
}, () => {
return delay(1003);
}, () => {
return delay(1005);
}, () => {
return delay(1002);
}, () => {
return delay(1004);
}, () => {
return delay(1006);
}];
/* Promise.all(tasks.map(task => task())).then(results => {
console.log(results);
}); */
let results = [];
asyncPool(2, tasks, (task, next) => {
task().then(result => {
results.push(result);
next(); //執(zhí)行下一個
});
}, () => {
console.log(results); //所有都完成
});
JS實現(xiàn)Ajax并發(fā)請求控制的兩大解決方案
// tasks:數(shù)組,數(shù)組包含很多方法,每一個方法執(zhí)行就是發(fā)送一個請求「基于Promise管理」
function createRequest(tasks, pool) {
pool = pool || 5;
let results = [],
together = new Array(pool).fill(null),
index = 0;
together = together.map(() => {
return new Promise((resolve, reject) => {
const run = function run() {
if (index >= tasks.length) {
resolve();
return;
};
let old_index = index,
task = tasks[index++];
task().then(result => {
results[old_index] = result;
run();
}).catch(reason => {
reject(reason);
});
};
run();
});
});
return Promise.all(together).then(() => results);
createRequest(tasks, 2).then(results => {
// 都成功,整體才是成功,按順序存儲結(jié)果
console.log('成功-->', results);
}).catch(reason => {
// 只要有也給失敗,整體就是失敗
console.log('失敗-->', reason);
});
}
function createRequest(tasks, pool, callback) {
if (typeof pool === "function") {
callback = pool;
pool = 5;
}
if (typeof pool !== "number") pool = 5;
if (typeof callback !== "function") callback = function () {};
//------
class TaskQueue {
running = 0;
queue = [];
results = [];
pushTask(task) {
let self = this;
self.queue.push(task);
self.next();
}
next() {
let self = this;
while (self.running < pool && self.queue.length) {
self.running++;
let task = self.queue.shift();
task().then(result => {
self.results.push(result); // 沒有管控順序
}).finally(() => { // 失敗之后繼續(xù)
self.running--;
self.next();
});
}
if (self.running === 0) callback(self.results);
}
}
let TQ = new TaskQueue;
tasks.forEach(task => TQ.pushTask(task));
}
createRequest(tasks, 2, results => {
console.log(results);
});
到了這里,關(guān)于AJAX并發(fā)請求控制的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!