献给异步编程的终极解答
// async await
首先先打个小广告,推荐一下之前写过的文章
- 1. 了解js单线程背后隐藏着的不为人知的秘密 事件循环Event Loop
- 2. 震惊,光天化日之下男子竟对Promise作出这样的事情( 指模拟promise)
实际上,如果你对前面这些概念了解的够深刻的话,async await其实相当的好理解,非常简单,简而言之就是,promise的出现让异步编程有着接近同步编程的体验,通过链式操作让你体验如丝般的顺滑回调写法,而async await的出现,则真正意义上改变了异步编程,实际上也就是将链式操作进一步剥离出来,具体的概念就不赘述了,详情可查看mdn的这篇 async await的文档 ,而主要讲一下个人对于async await怎么用,有什么用,的一些见解
async await能做什么
// 不要停下来啊
用法非常简单,适用于返回promise对象的异步函数例如,这里抛砖引玉,尝试用async await和promise实现一个事件订阅发布功能
- 其调用方式为,
context.$request(eventName)
,返回一个promise对象 - 其注册方式为,
context.$register(eventName, function (resolve, rejected) {})
首先是构造函数
const EventLoop = function () { this.table = [] this.queue = [] this.await = [] }
原型链部分,主要是事件处理和注册订阅部分
EventLoop.prototype.process = async function() { const { name, payload } = this.queue.shift() const func = this.table[name] if (this.queue.length > 0) { this.process() } else { this.readAwait() } if (typeof func == 'function') { return await func(payload) } else { this.await.push({ name, payload }) } } EventLoop.prototype.$register = function(name, executor) { this.table[name] = payload => { return new Promise((resolve, rejected) => { executor({ payload, resolve, rejected }) }) } this.readAwait() } EventLoop.prototype.$request = async function(name, payload) { this.queue.push({ name, payload }) return new Promise(async resolve => { await this.process() resolve() }) }
倘若注册事件还未发生,则需等待,await处理部分
EventLoop.prototype.readAwait = function() { for (let i = 0; i < this.await.length; i++) { const { name } = this.await[i] if (this.table[name]) { const queue = this.await.splice(i, 1) this.queue.push(...queue) this.process() break } } }