zoukankan      html  css  js  c++  java
  • JS 来实现一个 Promise

    promise A+ 规范简述

    • 一个promise必须有3个状态,pending,fulfilled(resolved),rejected当处于pending状态的时候,可以转移到fulfilled(resolved)或者rejected状态。当处于fulfilled(resolved)状态或者rejected状态的时候,就不可变。
    • 一个promise必须有一个then方法,then方法接受两个参数,resolve和reject
    • 实现链式调用,then方法必须返回一个promise

    promise A+ 源码

    Promise 源码:https://github.com/then/promise/blob/master/src/core.js

    一个简单的实现

    // this promise code refered to this blog
    // http://www.cnblogs.com/liuzhenwei/p/5235473.html
    var Promise = function (fn) {
        var state = 'pending';
        var doneList = [];
        var failList= [];
        this.then = function(done ,fail){
            switch(state){
                case 'pending':
                    doneList.push(done);
                    //每次如果没有推入fail方法,我也会推入一个null来占位
                    failList.push(fail || null);
                    return this;
                    break;
                case 'fulfilled':
                    done();
                    return this;
                    break;
                case 'rejected':
                    fail();
                    return this;
                    break;
            }
        }
        function tryToJson(obj) {
            var value;
            try {
                value = JSON.parse(obj);
            } catch (e) {
                value = obj;
            }
            return value
        }
        function resolve(newValue){
            state = 'fulfilled';
            setTimeout(function(){
                var value = tryToJson(newValue);
                for (var i = 0; i < doneList.length; i++){
                    var temp = doneList[i](value);
                    if (temp instanceof Promise) {
                        var newP = temp;
                        for (i++; i < doneList.length; i++) {
                            newP.then(doneList[i], failList[i]);
                        }
                    } else {
                        value = temp;
                    }
                }
            }, 0);
        }
        function reject(newValue){
            state = 'rejected';
            setTimeout(function(){
                var value = tryToJson(newValue);
                var tempRe = failList[0](value);
                //如果reject里面传入了一个promise,那么执行完此次的fail之后,将剩余的done和fail传入新的promise中
                if(tempRe instanceof Promise){
                    var newP = tempRe;
                    for (i=1;i<doneList.length;i++) {
                        newP.then(doneList[i],failList[i]);
                    }
                } else {
                    //如果不是promise,执行完当前的fail之后,继续执行doneList
                    value = tempRe;
                    doneList.shift();
                    failList.shift();
                    resolve(value);
                }
            }, 0);
        }
    
        fn(resolve,reject);
    }
    

    其实是把then方法里的回调函数分别推入doneList和failList中,然后在promiFn执行完毕后开始调用 function resolve(newValue){} 里更改state状态为fulfilled并且执行doneListi;

    var promiFn = function (resolve, reject) {
        setTimeout(function () {
            resolve(1)
        }, 0)
    };
    new Promise(promiFn)
    .then(function (d) {
        console.log(d)   
    }, function (e) {
        console.log(e);
    })
    

    promise 链式调用

    let bodyToJson = null;
    request('http:www.baidu.com')
    .then((d) => {
        return otherPromise;
    })
    .then((d) => {
        return anotherPromise
    })
    .then((d) => {
        // ...
    })
    .catch((err) => {
        // ...
    });
    

    还缺的 API

    • Promise.all
    • Promise.race
    • Promise.prototype.catch
    • Promise.prototype.finally

    等待完善。

    问题:为什么 promise 需要引入微任务

    Promise 中的执行函数是同步进行的,但是里面存在着异步操作,在异步操作结束后会调用 resolve 方法,或者中途遇到错误调用 reject 方法,这两者都是作为微任务进入到 EventLoop 中。但是你有没有想过,Promise 为什么要引入微任务的方式来进行回调操作?

    若 promise 回调放在进行宏任务队列的队尾,若队列非常长,那么回调迟迟得不到执行,造成的效果就是应用卡顿。所以就引入了微任务。

  • 相关阅读:
    NBU备份虚拟机高级选项virtual machine quiesce option
    find命令处理之exec与xargs区别
    python学习之列表
    vSphere 6.5密码正确不能登录解决方法
    Vmware vSphere P2V操作文档
    tomcat学习1架构理解
    telnet 退出命令
    敏捷软件开发
    数组、List和ArrayList的区别
    如何阅读一本书(感)
  • 原文地址:https://www.cnblogs.com/everlose/p/12501106.html
Copyright © 2011-2022 走看看