亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

新手如何快速理解js異步編程

2024-05-06 16:52:39
字體:
來源:轉載
供稿:網友

前言

異步編程從早期的 callback、事件發布/訂閱模式到 ES6 的 Promise、Generator 在到 ES2017 中 async,看似風格迥異,但是還是有一條暗線將它們串聯在一起的,就是希望將異步編程的代碼表達盡量地貼合自然語言的線性思維。

以這條暗線將上述幾種解決方案連在一起,就可以更好地理解異步編程的原理、魅力。
├── 事件發布/訂閱模式 <= Callback
├── Promise <= 事件發布/訂閱模式
├── Async、Await <= Promise、Generator

事件發布/訂閱模式 <= Callback

這個模式本質上就是回調函數的事件化。它本身并無同步、異步調用的問題,我們只是使用它來實現事件與回調函數之間的關聯。比較典型的有 NodeJS 的 events 模塊

const { EventEmitter } = require('events')const eventEmitter = new EventEmitter()// 訂閱eventEmitter.on("event", function(msg) {console.log("event", msg)})// 發布eventEmitter.emit("event", "Hello world")

那么這種模式是如何與 Callback 關聯的呢?我們可以利用 Javascript 簡單實現 EventEmitter,答案就顯而易見了。

class usrEventEmitter {constructor () {this.listeners = {}}// 訂閱,callback 為每個 event 的偵聽器on(eventName, callback) {if (!this.listeners[eventName]) this.listeners[eventName] = []this.listeners[eventName].push(callback)}// 發布emit(eventName, params) {this.listeners[eventName].forEach(callback => {callback(params)})}// 注銷off(eventName, callback) {const rest = this.listeners[eventName].fitler(elem => elem !== callback)this.listeners[eventName] = rest}// 訂閱一次once(eventName, callback) { const handler = function() {callback()this.off(eventName, handler)}this.on(eventName, handler)}}

上述實現忽略了很多細節,例如異常處理、多參數傳遞等。只是為了展示事件訂閱/發布模式。

很明顯的看出,我們使用這種設計模式對異步編程做了邏輯上的分離,將其語義化為

// 一些事件可能會被觸發eventEmitter.on// 當它發生的時候,要這樣處理eventEmitter.emit

也就是說,我們將最初的 Callback 變成了事件監聽器,從而優雅地解決異步編程。

Promise <= 事件發布/訂閱模式

使用事件發布/訂閱模式時,需要我們事先嚴謹地設置目標,也就是上面所說的,必須要縝密地設定好有哪些事件會發生。這與我們語言的線性思維很違和。那么有沒有一種方式可以解決這個問題,社區產出了 Promise。

const promise = new Promise(function(resolve, reject) {try {setTimeout(() => {resolve('hello world')}, 500)} catch (error) {reject(error)}})// 語義就變為先發生一些異步行為,then 我們應該這么處理promise.then(msg => console.log(msg)).catch(error => console.log('err', error))

那么這種 Promise 與事件發布/訂閱模式有什么聯系呢?我們可以利用 EventEmitter 來實現 Promise,這樣可能會對你有所啟發。

我們可以將 Promise 視為一個 EventEmitter,它包含了 { state: 'pending' } 來描述當前的狀態,同時偵聽它的變化

  • 當成功時 { state: 'fulfilled' },要做些什么 on('resolve', callback);
  • 當失敗時 { state: 'rejected' },要做些什么 on('reject', callback)。

具體實現如下

const { EventEmitter } = require('events')class usrPromise extends EventEmitter {// 構造時候執行constructor(executor) {super()// 發布const resolve = (value) => this.emit('resolve', value)const reject = (reason) => this.emit('reject', reason)if (executor) {// 模擬 event loop,注此處利用 Macrotask 來模擬 MicrotasksetTimeout(() => executor(resolve, reject))}}then(resolveHandler, rejectHandler) {const nextPromise = new usrPromise()// 訂閱 resolve 事件if (resolveHandler) {const resolve = (data) => {const result = resolveHandler(data)nextPromise.emit('resolve', result)}this.on('resolve', resolve)}// 訂閱 reject 事件if (rejectHandler) {const reject = (data) => {const result = rejectHandler(data)nextPromise.emit('reject', result)}this.on('reject', reject)} else {this.on('reject', (data) => {promise.emit('reject', data)})}return nextPromise}catch(handler) {this.on('reject', handler)}}

我們使用 then 方法來將預先需要定義的事件偵聽器存放起來,同時在 executor 中設定這些事件該在什么時候實行。

可以看出從事件發布/訂閱模式到 Promise,帶來了語義上的巨大變革,但是還是需要使用 new Promise 來描述整個狀態的轉換,那么有沒有更好地實現方式呢?

async、await <= Promise、Generator

async、await 標準是 ES 2017 引入,提供一種更加簡潔的異步解決方案。

async function say(greeting) {return new Promise(function(resolve, then) {setTimeout(function() {resolve(greeting)}, 1500)})};(async function() {let v1 = await say('Hello')console.log(v1)let v2 = await say('World')console.log(v2)})()

await 可以理解為暫停當前 async function 的執行,等待 Promise 處理完成。。若 Promise 正常處理(fulfilled),其回調的resolve函數參數作為 await 表達式的值。

async、await 的出現,減少了多個 then 的鏈式調用形式的代碼。下面我們結合 Promise 與 Generator 來實現 async、await

function async(makeGenerator) {return function() {const generator = makeGenerator.apply(this, arguments)function handle({ value, done }) {if (done === true) return Promise.resolve(value)return Promise.resolve(value).then((res) => {return handle(generator.next(res))},function(err) {return handle(generator.throw(err))})}try {return handle(generator.next())} catch (ex) {return Promise.reject(ex)}}}async(function*() {var v1 = yield say('hello')console.log(1, v1)var v2 = yield say('world')console.log(2, v2)})()

本質上就是利用遞歸完成 function* () { ... } 的自動執行。相比與 Generator 函數,這種形式無需手動執行,并且具有更好的語義。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值.


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久精品久久久久久国产 免费| 日韩精品在线视频观看| 国产精品久久不能| 亚洲女成人图区| 国产精品aaaa| 欧美亚洲免费电影| 成人中文字幕+乱码+中文字幕| 亚洲午夜av久久乱码| 亚洲性无码av在线| 在线日韩中文字幕| 综合国产在线视频| 国产精品免费一区豆花| 午夜剧场成人观在线视频免费观看| 国产精品自产拍在线观看中文| 亚洲男人天天操| 国产精品亚洲美女av网站| 国产在线精品播放| 亚洲欧美日韩在线一区| 久久久精品一区| 激情av一区二区| 成人在线中文字幕| 久久久久久12| 亚洲精品自在久久| 国产精品网站大全| 日韩av黄色在线观看| 欧美电影在线观看| 精品自在线视频| 欧美福利在线观看| 欧美性猛交xxx| 中文在线资源观看视频网站免费不卡| 欧美日韩在线免费观看| 欧美色视频日本版| 91av在线播放视频| 国产精品久久久久不卡| 日韩av在线不卡| 精品亚洲一区二区三区| 欧美日韩aaaa| 亚洲精品久久视频| 亚洲一区二区中文| 自拍偷拍亚洲欧美| 91精品国产成人www| 国产成人在线视频| 亚洲成人精品视频在线观看| 欧美激情在线有限公司| 自拍偷拍亚洲精品| 一道本无吗dⅴd在线播放一区| 性欧美xxxx视频在线观看| 欧美日韩在线免费| 欧美一级免费看| 欧美夫妻性生活视频| 久久精品国产电影| 2019亚洲男人天堂| 久久夜色精品国产亚洲aⅴ| 91黑丝在线观看| 国产日韩精品入口| 国产精品亚洲美女av网站| 久久久久久国产精品美女| 美女撒尿一区二区三区| 奇米影视亚洲狠狠色| 国产成人啪精品视频免费网| 97人人爽人人喊人人模波多| 中文字幕日韩电影| 国语自产精品视频在免费| 在线播放国产一区二区三区| 欧美黑人巨大精品一区二区| 欧美成人在线免费视频| 成人性生交大片免费看小说| 久久久人成影片一区二区三区观看| 国产日韩欧美日韩| 伊人伊成久久人综合网小说| 亚洲在线视频观看| 久久综合久中文字幕青草| 日本中文字幕不卡免费| 55夜色66夜色国产精品视频| 亚洲网站在线播放| 日韩av免费在线观看| 日韩欧美国产网站| 亚洲午夜未删减在线观看| 久久理论片午夜琪琪电影网| 国内外成人免费激情在线视频网站| 日韩精品视频免费在线观看| 成人国内精品久久久久一区| 亚洲精品一二区| 成人网页在线免费观看| 欧美国产极速在线| 日本一区二三区好的精华液| 国产日韩欧美中文在线播放| 国产成人一区三区| 国产精品狼人色视频一区| 91精品成人久久| 亚洲大尺度美女在线| 久久久亚洲精选| 欧美日韩另类字幕中文| 亚洲xxx视频| 热久久免费国产视频| 亚洲最大中文字幕| 日韩动漫免费观看电视剧高清| 国产ts人妖一区二区三区| 中文在线资源观看视频网站免费不卡| 国产精品久久久久久一区二区| 欧美激情视频三区| 国产精品免费看久久久香蕉| 午夜精品久久久久久久99黑人| 黑人巨大精品欧美一区二区| 精品福利一区二区| 亚洲欧美日韩国产成人| 欧美日韩国产二区| 在线观看免费高清视频97| 欧美老女人bb| 国产精品久久久久久久久久免费| 91精品久久久久久久久久入口| 亚洲成人在线视频播放| 欧美成人精品一区二区| 91在线精品播放| 亚洲乱码国产乱码精品精天堂| 亚洲国产精品成人av| 国产欧美精品一区二区| 日韩午夜在线视频| 国产免费亚洲高清| 欧美寡妇偷汉性猛交| 国产精品欧美激情在线播放| 欧美日韩中文字幕日韩欧美| 成人福利免费观看| 欧美日韩国产成人在线观看| 欧美丰满片xxx777| 精品亚洲一区二区三区在线播放| 久久久影视精品| 欧洲成人免费视频| 中文字幕欧美精品日韩中文字幕| 欧美激情一区二区三区成人| 日韩美女免费视频| 欧洲s码亚洲m码精品一区| 亚洲91av视频| 亚洲国产精品高清久久久| 成人福利视频在线观看| 久久视频中文字幕| 中文字幕亚洲欧美日韩2019| 亚洲国产高清福利视频| 欧美精品在线观看91| 亚洲国产精品中文| 在线观看日韩视频| 亚洲成人999| 欧美专区在线视频| 日韩毛片在线看| 欧美电影免费看| 国产精品欧美日韩| 中文字幕久精品免费视频| 欧美xxxx做受欧美.88| 777国产偷窥盗摄精品视频| 亚洲成人亚洲激情| 欧美日韩日本国产| 亚洲欧洲国产伦综合| 精品无人国产偷自产在线| 欧美在线视频网站| 国产+人+亚洲| 4388成人网| 国产精品久久一区主播| 国产精品第10页| 久久久噜久噜久久综合| 日韩福利视频在线观看| 久久影院模特热| 日韩免费在线播放| 国产成人精品综合| 国内精品久久久久久影视8|