动手实现一个简版Promise

摘要

Promise相信大家都用过,是ES6中新加入的语法,可以方便我们执行异步操作,并且能够链式调用,一定程度上缓解了callbackHell(回调地狱)的状况,使用起来十分方便,然后很多同学缺知其然不知其所以然,本文就会用十分简短的代码和详细的流程图来帮助大家理解Promise是如何进行异步操作以及如何实现链式调用的。

前言

本文适合有一定Promise使用基础的人阅读,如果不清楚请移步阮一峰老师的Promise入门

Promise的规范非常多,例如Promise/A,Promise/B,Promise/D,还有升级版Promise/A+,ES6中的Promise就是依据Promise/A+规范进行实现的,但是对于我们手写简易版来说的话太长了,不利于大家快速上手(PS:对于面试中的考察如果按照Promise/A+规范去写,那写到天荒地老吧哈哈)。阅读完本文在去看Promise/A+规范,相信会更好理解,Promise/A+规范还是非常有必要去阅读理解的。

本次实现的简易版Promise不考虑任何边界情况,只从最简短便于读者理解核心的异步链式调用。

代码


function Promise(fn) {
    this.cbs = []
    const resolve = value => {
        queueMicrotask(() => {
            this.cbs.forEach(cb => cb(value))
        })
    }
    fn(resolve)
}
Promise.prototype.then = function(resolveCallback) {
    return new Promise(resolve => {
        this.cbs.push(function(value) {
            const res = resolveCallback(value)
            if(res instanceof Promise) {
                res.then(resolve)
            } else {
                resolve(res)
            }
        })
    })
}

上面代码大概只有20行左右,非常简单,但是内部的调用比较绕。

案例


new Promise(resolve => {
    setTimeout(() => {
        resolve('HEHE')
    }, 1000);
}).then(function(res) {
    console.log(res)
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(res+'哈哈')
        }, 2000);
    })
}).then(function(res1) {
    console.log(res1)
    return 'end'
})

流程图

本图按照上面的案例进行绘制,

代码表现如下:

  1. 1000ms后输出"HEHE"
  2. 再过2000ms后输出"HEHE哈哈"


    Promise链式调用流程解析.png

总结

本文实现了一个简单的Promise,仅支持链式异步调用,ES6真正的Promise是非常复杂的,涉及到了多种边界情况的处理,最后还是推荐大家去阅读一下Promise/A+规范,有能力的可以根据Promise/A+规范手写一个自己的Promise。

以上,谢谢大家,看完可以给个关注啵~

你可能感兴趣的:(动手实现一个简版Promise)