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