美文网首页
JavaScript异步与Promise实现

JavaScript异步与Promise实现

作者: 凡凡的小web | 来源:发表于2020-03-10 23:16 被阅读0次

    原文https://zhuanlan.zhihu.com/p/26815654

    Promise实现
    Promise是什么,怎么样使用就介绍到此,另外一个问题是面试过程中经常也会被提及的:如何实现一个Promise,当然,限于篇幅,我们这里只讲思路,不会长篇大论。

    构造函数
    首先创建一个构造函数,供实例化创建promise,该构造函数接受一个函数参数,实例化时,会立即调用该函数,然后返回一个Promise对象:

    var MyPromise = (() => {
    var value = undefined; // 当前Promise
    var tasks = []; // 完成回调队列
    var rejectTasks = []; // 拒绝回调队列
    var state = 'pending'; // Promise初始为等待态

        // 辅助函数,使异步回调下一轮事件循环执行
        var nextTick = (callback) => {
            setTimeout(callback, 0);
        };
    
        // 辅助函数,传递Promsie的状态值
        var ref = (value) => {
            if (value && typeof value.then === 'function') {
                // 若状态值为thenable对象或Promise,直接返回
                return value;
            }
            // 否则,将最终值传递给下一个then方法注册的回调函数
            return {
                then: function(callback) {
                    return ref(callback(value));
                }
            }
        };
        var resolve = (val) => {};
        var reject = (reason) => {};
    
        function MyPromise(func) {
            func(resolve.bind(this), reject.bind(this));
        }
    
        return MyPromise;
    });
    

    静态方法
    在实例化创建Promise时,我们会将构造函数的两个静态方法:resolve和reject传入初始函数,接下来需要实现这两个函数:

    var resolve = (val) => {
    if (tasks) {
    value = ref(val);
    state = 'resolved'; // 将状态标记为已完成
    // 依次执行任务回调
    tasks.forEach((task) => {
    value = nextTick((val) => {task0;});
    });
    tasks = undefined; // 决议后状态不可变

            return this;
        }
    };
    var reject = (reason) => {
        if (tasks) {
            value = ref(reason);
            state = 'rejected'; // 将状态标记为已完成
    
            // 依次执行任务回调
            tasks.forEach((task) => {
                nextTick((reason) => {task[1](value);});
            });
            tasks = undefined; // 决议后状态不可变
    
            return this;
        }
    };
    

    还有另外两个静态方法,原理还是一样,就不细说了。

    实例方法
    目前构造函数,和静态方法完成和拒绝Promise都已经实现,接下来需要考虑的是Promise的实例方法和链式调用:

    MyPromise.prototype.then = (onFulfilled, onRejected) => {
        onFulfilled = onFulfilled || function(value) {
            // 默认的完成回调
            return value;
        };
        onRejected = onRejected || function(reason) {
            // 默认的拒绝回调
            return reject(reason);
        };
    
        if (tasks) {
            // 未决议时加入队列
             tasks.push(onFulfilled);
             rejectTasks.push(onRejected);
        } else {
            // 已决议,直接加入事件循环执行
             nextTick(() => {
                 if (state === 'resolved') {
                     value.then(onFulfilled);
                 } else if (state === 'rejected') {
                     value.then(onRejected);
                 }
             });
        }
    
        return this;
    };
    

    实例
    以上可以简单实现Promise部分异步管理功能:

    var promise = new MyPromise((resolve, reject) => {
        setTimeout(() => {
            resolve('完成');
        }, 0);
    });
    promise.then((msg) => {console.log(msg);});
    

    本篇由回调函数起,介绍了回调处理异步任务的常见问题,然后介绍Promises/A+规范及Promise使用,最后就Promise实现做了简单阐述(之后有机会会详细实现一个Promise),花费一周终于把基本知识点介绍完,下一篇将介绍JavaScript异步与生成器实现。

    相关文章

      网友评论

          本文标题:JavaScript异步与Promise实现

          本文链接:https://www.haomeiwen.com/subject/mhcodhtx.html