1.什么是異步:任務(wù)與任務(wù)之間是不存在等待的關(guān)系 前一個任務(wù)完成之后等待回調(diào) 中間并不影響后面隊列中任務(wù)的執(zhí)行
1.首先記住一句話 —— JS 是單線程的語言李请,所謂“單線程”就是一根筋萌腿,對于拿到的程序,一行一行的執(zhí)行,上面的執(zhí)行為完成辰斋,就傻傻的等著铸屉。
var i, t = Date.now()
for (i = 0; i < 100000000; i++) {
}//等待循環(huán)遍歷結(jié)束 才會進(jìn)行下面的
console.log(Date.now() - t) // 250 (chrome瀏覽器)
通過上面的程序我們可以了解到 如果是單純的之sing程序 我們可以等 但是對于再瀏覽區(qū)里面運行的 代碼 我們不可能因為某一段代碼的執(zhí)行占用大量的時間而傻傻的等著 這時異步的理念就顯得尤為關(guān)鍵了。
2.引出異步概念的原因-- 避免 DOM 渲染沖突
// 避免 DOM 渲染沖突
// 1.瀏覽器需要渲染DOM
// 2.JS可以修改DOM結(jié)構(gòu)
// 3,JS執(zhí)行的時候岖妄,瀏覽器DOM渲染會暫停
// 4.兩端JS也不能同時修改(同時修改避免DOM沖突)
// 5,webeorker支持多線程但是不能操作DOM
1.說到異步 我們就要引出單線程的概念
2 瀏覽器內(nèi)核的多線程
瀏覽器的內(nèi)核是多線程的型将,他們在內(nèi)核的控制下互相配合以保持同步,一個瀏覽器至少實現(xiàn)三個常駐的線程:
1.javascript引擎線程荐虐,(用于事件處理的機(jī)制)
2.GUI渲染線程七兜,
3.瀏覽器事件觸發(fā)線程。
1)js引擎福扬,基于事件驅(qū)動單線程執(zhí)行的腕铸,js引擎一直等待著任務(wù)隊列中任務(wù)的到來,然后加以處理铛碑,瀏覽器無論什么時候都只有一個JS線程在運行JS程序狠裹。
2)GUI線程,當(dāng)界面需要重繪或由于某種操作引發(fā)回流時汽烦,該線程就會執(zhí)行涛菠。它和JS引擎是互斥的。
3)瀏覽器事件觸發(fā)線程撇吞,當(dāng)一個事件被觸發(fā)時俗冻,該線程會把事件添加到待處理隊列的隊尾,等待js引擎的處理牍颈,這些事件可來自JavaScript引擎當(dāng)前執(zhí)行的代碼塊如迄薄,setTimeOut, 也可以來自瀏覽器內(nèi)核的其他線程如鼠標(biāo)點擊,AJAX異步請求等煮岁,但由于JS的單線程關(guān)系讥蔽,所有這些事件都得排隊等待JS引擎處理。
3 事件循環(huán)機(jī)制
3.異步的解決方案-異步編程實現(xiàn)
1 回調(diào)函數(shù)
// 一個簡單的封裝
function want() {
console.log('這是你想要執(zhí)行的代碼');
}
function fn(want) {
console.log('這里表示執(zhí)行了一大堆各種代碼');
// 其他代碼執(zhí)行完畢画机,最后執(zhí)行回調(diào)函數(shù)
want && want();
}
fn(want);
doSomethingAsync1(function(){
doSomethingAsync2(function(){
doSomethingAsync3(function(){
doSomethingAsync4(function(){
doSomethingAsync5(function(){
// code...
});
});
});
});
});
總結(jié):上面代碼我們可以看到在代碼層面嵌套不太深的情況下我們還好維護(hù)冶伞,而一旦嵌套層次過多就會形成 回調(diào)金字塔 很難維護(hù)--回調(diào)地獄
2 事件監(jiān)聽(事件發(fā)布/訂閱)
》》》事件監(jiān)聽是一種非常常見的異步編程模式蹂季,它是一種典型的邏輯分離方式典徘,對代碼解耦很有用處。通常情況下阱缓,我們需要考慮哪些部分是不變的戳护,哪些是容易變化的金抡,把不變的部分封裝在組件內(nèi)部瀑焦,供外部調(diào)用,需要自定義的部分暴露在外部處理梗肝。從某種意義上說榛瓮,事件的設(shè)計就是組件的接口設(shè)計。
1)jQuery事件監(jiān)聽
$('#btn').on('myEvent', function(e) {
console.log('There is my Event');
});
$('#btn').trigger('myEvent');
2)發(fā)布/訂閱模式
var PubSub = function(){
this.handlers = {};
};
PubSub.prototype.subscribe = function(eventType, handler) {
if (!(eventType in this.handlers)) {
this.handlers[eventType] = [];
}
this.handlers[eventType].push(handler); //添加事件監(jiān)聽器
return this;//返回上下文環(huán)境以實現(xiàn)鏈?zhǔn)秸{(diào)用
};
PubSub.prototype.publish = function(eventType) {
var _args = Array.prototype.slice.call(arguments, 1);
for (var i = 0, _handlers = this.handlers[eventType]; i < _handlers.length; i++) {
_handlers[i].apply(this, _args);//遍歷事件監(jiān)聽器
}
return this;
};
var event = new PubSub;//構(gòu)造PubSub實例
event.subscribe('list', function(msg) {
console.log(msg);
});
event.publish('list', {data: ['one,', 'two']});
//Object {data: Array[2]}
3.3 Promise對象
import axios from 'axios';
import iView from "iview";
let qs = require("qs");
axios.defaults.timeout = 50000;
axios.defaults.baseURL = '';
function http(config) {
return new Promise((resolve, reject) => {
axios(config).then(response => {
let reqUrl = response.request.responseURL;
try {
if (!reqUrl.endsWith("callNum.action") && !reqUrl.endsWith("getMicroDeviceStatus.action")) {
if (response.data.code === 401) {
top.window.location.href = "/login.html";
} else if (response.data.code === 403) {
iView.Message.error('權(quán)限不足巫击,禁止訪問禀晓!');
} else if (response.data.code === 500) {
if (response.data.msg) {
iView.Message.error(response.data.msg);
} else {
iView.Message.error('網(wǎng)絡(luò)訪問失敗,請稍后再試坝锰!');
}
} else if (response.data.code !== 200) {
iView.Message.error(response.data.msg);
}
}
} catch (e) {}
resolve(response.data);
}).catch(err => {
if (!reqUrl.endsWith("getMicroDeviceStatus.action")) {
iView.Message.error('網(wǎng)絡(luò)請求發(fā)生錯誤粹懒!');
}
reject(err);
});
});
}
/**
* 封裝get方法
* @param url 要請求的url地址
* @param params 請求的參數(shù)
* @returns {Promise}
*/
export function fetch(url, params = {}) {
return http({
method: 'GET',
url: url,
params: params,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'platform': 'PC'
}
});
}
/**
* 封裝post請求
* @param url 要請求的url地址
* @param data 請求的參數(shù)
* @returns {Promise}
*/
export function post(url, data = {}) {
return http({
method: 'POST',
url: url,
data: qs.stringify(data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'platform': 'PC'
}
});
}
/**
* 封裝patch請求
* @param url 要請求的url地址
* @param data 請求的參數(shù)
* @returns {Promise}
*/
export function patch(url, data = {}) {
return http({
method: 'PATCH',
url: url,
data: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'platform': 'PC'
}
});
}
/**
* 封裝put請求
* @param url 要請求的url地址
* @param data 請求的參數(shù)
* @returns {Promise}
*/
export function put(url, data = {}) {
return http({
method: 'PUT',
url: url,
data: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'platform': 'PC'
}
});
}
//get請求
async handleGetRulesData(){
let reqUrl = this.global.baseUrl + "/pc/robotAnalyzer/rule";
let params = {};
let data = await this.$fetch(reqUrl,params);
if(data.code==200){
}
},
、顷级、post請求
async handleRobotAnalySort(){
let reqUrl = this.global.baseUrl + "/pc/robotAnalyzer/sort/"+this.robotId;
let params = {};
let data = await this.$post(reqUrl,params);
if(data.code==200){
}
},