• Geek_Jamorx
    2019-09-17
    这三个题目非常重要,就跟做笔记一样回答了
    1、Promise 中为什么要引入微任务?

    由于promise采用.then延时绑定回调机制,而new Promise时又需要直接执行promise中的方法,即发生了先执行方法后添加回调的过程,此时需等待then方法绑定两个回调后才能继续执行方法回调,便可将回调添加到当前js调用栈中执行结束后的任务队列中,由于宏任务较多容易堵塞,则采用了微任务

    2、Promise 中是如何实现回调函数返回值穿透的?
    首先Promise的执行结果保存在promise的data变量中,然后是.then方法返回值为使用resolved或rejected回调方法新建的一个promise对象,即例如成功则返回new Promise(resolved),将前一个promise的data值赋给新建的promise

    3、Promise 出错后,是怎么通过“冒泡”传递给最后那个捕获
    promise内部有resolved_和rejected_变量保存成功和失败的回调,进入.then(resolved,rejected)时会判断rejected参数是否为函数,若是函数,错误时使用rejected处理错误;若不是,则错误时直接throw错误,一直传递到最后的捕获,若最后没有被捕获,则会报错。可通过监听unhandledrejection事件捕获未处理的promise错误



    展开
     3
     23
  • 皮皮大神
    2019-09-18
    老师,我觉得这章没有前面的讲得透彻,手写的bromise非常不完整,希望老师答疑的时候可以带我们写一遍完整promise源码,三种状态的切换,还有.then为什么可以连续调用,内部如何解决多层异步嵌套,我觉得都很值得讲解,老师带我们飞。

    作者回复: 这个加餐可以有!

    这篇问题主要在宏观视角建立对Promise的认知。

    关于手写 或者细节内容课程结束之后我们慢慢聊。

    目前被编辑追稿子压力大,好多问题没及时回复还望理解哈。课程结束之后我会相信回复大家的问题的。

     2
     7
  • Rapheal
    2019-10-05
    Promise的改进版,测试过也无问题。之前使用闭包存放所有回调函数有些问题,所有的Promise对象都是共享,这样会造成全局数据结构有问题。当前是基于回调函数数组传递在Promise对象之间传递实现。


        function _Promise(executor) {
            this._resolve = [];
            this._reject = [];
            this._catch;

            /*临时保存引用*/
            let self = this;
            
            this.then = function (resolve, reject) {
                resolve && this._resolve.push(resolve);
                reject && this._reject.push(reject);
                return this;
            }

            
            this.resolve = function (data) {
                setTimeout(() => {
                    let callback = self._resolve.shift();
                    self._reject && self._reject.shift();
                    let pro;
                    callback && (pro = callback(data));
                    self._resolve && (pro._resolve = self._resolve);
                    self._reject && (pro._reject = self._reject);
                    self._catch && (pro._catch = self._catch);

                }, 0)
            }

            this.reject = function (error) {
                setTimeout(() => {
                    let callback;
                    self._reject && (callback = self._reject.shift());
                    callback && callback(error);
                    callback || self._catch(error);

                }, 0);
            }

            this.catch = function (callback) {
                this._catch = callback;
                return this;
            }
            executor(this.resolve, this.reject);
        }


    function executor(resolve, reject) {
        let rand = Math.random();
        console.log(1)
        console.log(rand)
        if (rand > 0.5)
            resolve(rand)
        else
            reject(rand)
    }
    var p0 = new _Promise(executor);

    var p1 = p0.then((value) => {
        console.log("succeed-1")
        return new _Promise(executor)
    })

    var p3 = p1.then((value) => {
        console.log("succeed-2")
        return new _Promise(executor)
    })

    var p4 = p3.then((value) => {
        console.log("succeed-3")
        return new _Promise(executor)
    })

    p4.catch((error) => {
        console.log("error")
    })


    console.log(2)
    展开
    
     3
  • 空间
    2019-09-18
    异步AJAX请求是宏任务吧?Promise是微任务,那么用Promise进行的异步Ajax调用时宏任务还是微任务?

    作者回复: ajax就是xmlhttprequest,必然是宏任务!

    准确地说,Promise在执行resolve或者reject时,触发微任务,所以在Promise的executor函数中调用xmlhttprequest会触发宏任务。

    如果xmlhttprequest请求成功了,通过resolve触发微任务

    如果xmlhttprequest请求失败了,通过reject触发微任务

    
     3
  • Angus
    2019-09-20
    看完这节之后我自己去实现了手写Promise,回顾了一下Promise,关于这方面的文章很多,我觉得老师大可不必在这里花大量篇幅去讲。专栏的名字是浏览器工作原理与实践,所以我希望老师能够更加着重这一方面的讲解。
     1
     2
  • 胖虎
    2019-11-22
    "回调函数返回值穿透到最外层" 这句话配合老师您讲的例子是错误的 return x2 这个x2按照您那种方式没办法返回到最外层 最外层的x2和里面函数return 出来的x2根本就是两个东西
    
     1
  • Hurry
    2019-09-20
    这个太赞了 “ Promise 通过回调函数延迟绑定、回调函数返回值穿透和和错误“冒泡”技术 “, 之前看到别人手写实现 Promise,代码虽然可以看懂,但是理解不深,所以关键还是看如何实现这个三个点 回调函数延迟绑定、回调函数返回值穿透和和错误“冒泡”,结合这三个点和 promise API,手写一个 Promise, So easy

    ```js
    class PromiseSimple {
      constructor(executionFunction) {
        this.promiseChain = []; // 1.通过数组存储 callback,实现callback 延迟执行
        this.handleError = () => {};

        this.onResolve = this.onResolve.bind(this);
        this.onReject = this.onReject.bind(this);

        executionFunction(this.onResolve, this.onReject);
      }

      then(onResolve) {
        this.promiseChain.push(onResolve);

        return this;
      }

      catch(handleError) {
        this.handleError = handleError;

        return this;
      }

      onResolve(value) {
        let storedValue = value;

        try {
          this.promiseChain.forEach((nextFunction) => {
             storedValue = nextFunction(storedValue); // 2.循环,实现 callback 值传递
          });
        } catch (error) { // 3. try catch, 实现错误值冒泡
          this.promiseChain = [];

          this.onReject(error);
        }
      }

      onReject(error) {
        this.handleError(error);
      }
    }
    ```
    展开
     1
     1
  • Chao
    2019-09-17
    老师 你有答疑环节吗

    作者回复: 有,现在写稿子时间紧,等我主要稿件写完会抽出大把时间来专门解答问题。

     1
     1
  • 許敲敲
    2019-09-17
    面试手写promise也不怕了

    作者回复: 手写我加餐来讲

    
     1
  • 任振鹏
    2019-12-07
    老师 渲染流水线 在 微任务 之前 还是 之后 执行啊?

    作者回复: 微任务也可以不触发渲染操作,也可以出发渲染操作!

    比如你也可以在微任务中通过js来修改dom,触发重绘,重排等动作!

    你也可以在微任务中执行一些逻辑运算,这就和页面渲染没有关系了!

    
    
  • lisiur
    2019-11-26
    then函数为什么延时绑定就需要在微任务里执行resolve?先将结果保存下来,什么时候调用then函数时就把结果抛出去不行吗?
    
    
  • 昆虫捕手
    2019-11-21
    老师,文中用promise重构XFetch代码中,resolve接收了两个参数,第二个参数this的作用是什么,没看懂,希望老师解答下。
    
    
  • Geek_6b0898
    2019-11-12
    想问下老师什么时候给加餐课?支持老师尽快出啊

    作者回复: 快了,快了,最近家里小孩生病住院,折腾了好久,刚出院!

    
    
  • 凭实力写bug
    2019-11-03
    我比较想知道promise微任务的功能是怎么实现的
    
    
  • 蓝配鸡
    2019-11-01
    请问老师你用的什么工具画图?

    作者回复: mac下的keynote

    
    
  • Rapheal
    2019-10-05
    自己手写了一个_Promise,运行老师上面的程序,没啥毛病。除了使用宏任务,可以解决嵌套和参数穿透问题。


    var _Promise = (function () {
        
        /*使用闭包 保存所有的回调函数 */
        var _resolve = [];
        var _reject = [];
        var _catch;

        return function (executor) {

            this.print = function () {
                console.log(_resolve)
                console.log(_catch)

            }
            this.then = function (resolve, reject) {
                resolve && _resolve.push(resolve);
                reject && _reject.push(reject);
                return this;
            }

            this.resolve = function (data) {
                setTimeout(function () {
                    let callback = _resolve.shift();
                    let pro;
                    callback && (pro = callback(data));
                    _reject.shift();

                }, 0)
            }

            this.reject = function (error) {
                setTimeout(function () {
                    let callback = _reject.shift();
                    callback && callback(error);
                    callback || _catch(error);

                }, 0);
            }

            this.catch = function (callback) {
                _catch = callback;
                return this;
            }
            executor(this.resolve, this.reject);
        }
    })()

    function executor(resolve, reject) {
        let rand = Math.random();
        console.log(1)
        console.log(rand)
        if (rand > 0.5)
            resolve(rand)
        else
            reject(rand)
    }
    var p0 = new _Promise(executor);

    var p1 = p0.then((value) => {
        console.log("succeed-1")
        return new _Promise(executor)
    })

    var p3 = p1.then((value) => {
        console.log("succeed-2")
        return new _Promise(executor)
    })

    var p4 = p3.then((value) => {
        console.log("succeed-3")
        return new _Promise(executor)
    })

    p4.catch((error) => {
        console.log("error")
    })


    console.log(2)
    展开
    
    
  • tick
    2019-09-24
    Bromise实现的then是不是不太对,then是要有返回Promise的,我理解Promise对吧?
    
    
  • 柒月
    2019-09-20
    很棒,那个Bromise的代码绕了半天总算看明白了
    
    
  • 李懂
    2019-09-19
    问个问题,看了好多库发送一个请求new XMLHttpRequest(),咋不使用单例,发送请求共用一个或者请求对象池!
     1
    
  • 瞧,这个人
    2019-09-19
    老师会在加班课里给大家讲解典型课后思考题吗

    作者回复: 会的,可以把你的问题列出来,我答疑时会有针对性

    
    
我们在线,来聊聊吧