相親網(wǎng)站做期貨現(xiàn)貨貴金屬的人開(kāi)車(chē)搜索關(guān)鍵詞
前言
為了解決Javascript 語(yǔ)言的執(zhí)行環(huán)境是單線(xiàn)程所帶來(lái)的問(wèn)題,Javascript 將任務(wù)的執(zhí)行模式分為兩種:同步和異步
同步即為后一個(gè)任務(wù)等待前一個(gè)任務(wù)結(jié)束再繼續(xù)執(zhí)行,程序的執(zhí)行順序與任務(wù)的排列順序是一致的
異步則完全不同,每一個(gè)任務(wù)都有一個(gè)或者多個(gè)回調(diào)函數(shù),前一個(gè)任務(wù)結(jié)束后,不是執(zhí)行后一個(gè)任務(wù)而是執(zhí)行回調(diào)函數(shù),后一個(gè)任務(wù)則是不等待前一個(gè)任務(wù)執(zhí)行結(jié)束就執(zhí)行。因此,程序的執(zhí)行順序與任務(wù)的排列是不一致的、異步的。在瀏覽器端,耗時(shí)很長(zhǎng)的操作都應(yīng)該異步執(zhí)行,從而避免瀏覽器失去響應(yīng)。在服務(wù)端,異步模式甚至是唯一的模式,因?yàn)閳?zhí)行環(huán)境是單線(xiàn)程的,如果同步執(zhí)行所有的 http 請(qǐng)求,服務(wù)器的性能會(huì)急劇下降。
異步解決方案
回調(diào)函數(shù) callback
回調(diào)函數(shù),簡(jiǎn)單來(lái)說(shuō)就是一個(gè)函數(shù)作為參數(shù)傳遞給另一個(gè)函數(shù)
回調(diào)并不一定就是異步,并沒(méi)有直接關(guān)系,只不過(guò)回調(diào)函數(shù)是異步的一種解決方案
// 同步
function fn1(callback){console.log("1")callback && callback()
}function fn2(){console.log("2")
}fn1(fn2)// 異步
function fn1(callback){setTimeout(() => {callback && callback()}, 1000)
}function fn2(){console.log("2")
}fn1(fn2)
缺點(diǎn):
- 代碼不優(yōu)雅
- 不易閱讀維護(hù)
- 高耦合,層層嵌套造成這種回調(diào)地獄
- 異步回調(diào)中,回調(diào)函數(shù)的執(zhí)行棧與原函數(shù)分離開(kāi),外部無(wú)法抓住異常,異常會(huì)變得不可控
事件監(jiān)聽(tīng)(發(fā)布訂閱模式)
class EventEmitter {constructor() {this.events = {};}// 訂閱指定的事件on(event, listener) {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(listener);}// 取消訂閱指定的事件off(event, listenerToRemove) {if (!this.events[event]) {return;}this.events[event] = this.events[event].filter(listener => listener !== listenerToRemove);}// 觸發(fā)指定的事件,并傳遞數(shù)據(jù)給事件監(jiān)聽(tīng)器emit(event, ...args) {if (!this.events[event]) {return;}this.events[event].forEach(listener => {listener.apply(this, args);});}
}// 使用 EventEmitter 的例子// 創(chuàng)建一個(gè)事件發(fā)射器的實(shí)例
const eventEmitter = new EventEmitter();// 創(chuàng)建監(jiān)聽(tīng)事件
const onMessage = (message) => {console.log(`Received message: ${message}`);
};// 將監(jiān)聽(tīng)器綁定到事件 'message'
eventEmitter.on('message', onMessage);// 觸發(fā)事件 'message',并傳遞數(shù)據(jù)
eventEmitter.emit('message', 'Hello World!'); // 輸出: Received message: Hello World!// 取消訂閱
eventEmitter.off('message', onMessage);// 再次觸發(fā)事件 'message',此時(shí)沒(méi)有監(jiān)聽(tīng)器監(jiān)聽(tīng)這個(gè)事件,因此不會(huì)有輸出
eventEmitter.emit('message', 'Hello again!');
Promise
ES6(ECMAScript 2015)引入了Promise,它是一種對(duì)異步操作進(jìn)行管理的機(jī)制。Promise 代表一個(gè)尚未完成但預(yù)期將來(lái)會(huì)完成的異步操作的結(jié)果。它可以解決傳統(tǒng)的回調(diào)地獄問(wèn)題,提供更加優(yōu)雅的異步代碼管理方式,具備以下特點(diǎn):
狀態(tài)不可逆:Promise有三種狀態(tài):pending(進(jìn)行中),fulfilled(已成功)和rejected(已失敗)。狀態(tài)改變只能從 pending 到 fulfilled 或從 pending 到 rejected,狀態(tài)一旦改變,就不會(huì)再變。
異步結(jié)果的占位符:Promise 起到一個(gè)代理的作用,允許你在異步操作未完成時(shí)安排代碼以響應(yīng)式的成功(fulfilled)或失敗(rejected)。
示例和基本用法:
// 創(chuàng)建一個(gè)新的 Promise 對(duì)象
let promise = new Promise(function(resolve, reject) {// 異步操作setTimeout(() => {// 成功的異步操作resolve('Data received');// 或者一個(gè)失敗的異步操作// reject(new Error('Failed to receive data'));}, 1000);
});// 使用 then 方法設(shè)置當(dāng) promise 狀態(tài)變?yōu)?fulfilled 時(shí)應(yīng)該執(zhí)行的代碼
promise.then(function(value) {console.log(value);
}, function(error) {console.error(error);
});// 使用 catch 方法來(lái)捕獲異常
promise.catch(function(error) {console.error('There was an error', error);
});
Promise的方法:
- then(onFulfilled, onRejected):then方法返回一個(gè)新的 Promise。它接受兩個(gè)函數(shù)作為參數(shù)。第一個(gè)函數(shù)在Promise成功時(shí)調(diào)用,并接受成功的值作為參數(shù)。第二個(gè)函數(shù)在Promise失敗時(shí)調(diào)用,并接受錯(cuò)誤或拒絕的理由作為參數(shù)。
- catch(onRejected):捕獲 Promise 中發(fā)生的任何異常,等同于.then(null, onRejected)。
- finally(onFinally):無(wú)論 Promise 最終的狀態(tài)如何,都會(huì)執(zhí)行onFinally回調(diào),而且不接收任何參數(shù)。它通常用于清理操作,比如停止加載指示器。
此外,Promise API 還提供了幾個(gè)靜態(tài)方法用于處理多個(gè)Promise:
- Promise.all(iterable):接受一個(gè) Promise 對(duì)象的集合作為輸入,當(dāng)這些對(duì)象全部成功時(shí)才觸發(fā)成功。
- Promise.race(iterable):同樣接受一個(gè)集合,但只要其中的一個(gè) Promise 對(duì)象改變狀態(tài),返回的 promise 對(duì)象就會(huì)隨之改變狀態(tài)。
- Promise.resolve(value):返回一個(gè)以給定值解析后的 Promise 對(duì)象。
- Promise.reject(reason):返回一個(gè)以給定理由拒絕的 Promise 對(duì)象。
Promise 提高了異步代碼的可讀性和可維護(hù)性,并且是許多現(xiàn)代JavaScript異步編程的基石。
Async/Await
TODO
Async/Await = Generator + Promise