zoukankan      html  css  js  c++  java
  • jQuery的链式调用原理,Promise的链式调用,this的问题

    最近被问到这个问题,jq的链式调用原理,当时比较懵=。=,毕竟现在jq接触的机会变很少了。

    jq的链式调用

    jq的链式调用其实就是比如我们在选择dom的时候,

    $('input[type="button"]')
        .eq(0).click(function() {
            alert('点击我!');
    }).end().eq(1)
    .click(function() {
        $('input[type="button"]:eq(0)').trigger('click');
    }).end().eq(2)
    .toggle(function() {
        $('.aa').hide('slow');
    }, function() {
        $('.aa').show('slow');
    });
    

    比如如上代码,先选择type类型为button的所有DOM,然后再选择第一个...

    我们自然想到每次其实就是返回选择后的结果,在js里面有什么东西可以指代这个吗?
    如果你想到this就对了。

    jq的方法都是挂在原型的,那么如果我们每次在内部方法返回this,也就是返回实例对象,那么我们就可以继续调用原型上的方法了,这样的就节省代码量,提高代码的效率,代码看起来更优雅。

    但是也会出现一个问题:所有对象的方法返回的都是对象本身,也就是说没有返回值,所以这种方法不一定在任何环境下都适合。

    Promise的链式调用

    promise的链式调用如:

    function start() {  
        return new Promise((resolve, reject) => {  
          resolve('start');  
        });  
      }  
        
      start()  
        .then(data => {  
          // promise start  
          console.log('result of start: ', data);  
          return Promise.resolve(1); // p1  
        })  
        .then(data => {  
          // promise p1  
          console.log('result of p1: ', data);  
          return Promise.reject(2); // p2  
        })  
        .then(data => {  
          // promise p2  
          console.log('result of p2: ', data);  
          return Promise.resolve(3); // p3  
        })  
        .catch(ex => {  
          // promise p3  
          console.log('ex: ', ex);  
          return Promise.resolve(4); // p4  
        })  
        .then(data => {  
          // promise p4  
          console.log('result of p4: ', data);  
        });  
    

    Promise的then其实都是实现了 thenable 接口,每个 then 都返回一个新的promise,除了第一个是start的实例其他的已经不是一个promise了。

    reject的下面的then都会跳过(

    更新

    这里其实说错了,应该是then 里面的回调被忽略执行,如果在这个then直接写一个console.log()你发现还是会打印,感谢jjc大佬特别指出这一点的错误,当 Promise 的状态为 rejected 时,这个回调函数没有被执行,并不是 then 函数没有被执行。

    eg:

    Promise.reject(1).then(console.log('foo bar'));
    

    依然输出了 foo bar,可见 then 函数其实已经执行了。
    如果写成:

    Promise.reject(1).then(() => console.log('foo bar'));
    

    就不会输出了。只是说,then 函数中传入了一个回调函数,当 Promise 的状态为 rejected 时,这个回调函数没有被执行,并不是 then 函数没有被执行。

    做个合适的类比。以下 jQuery 链式调用:

    $('#a_id_selector')
      .addClass('someclassname')
      .click(() => console.log('foo bar'))
      .prop('type', 'text');
    

    运行这段代码,也没有输出 foo bar,但是我们不能说 click 函数被忽略掉了。只是里面传入的回调函数的条件没有成立,这里是点击的条件,上面就是resolve的条件。

    ),只有catch才会捕捉到。

    promise的链式调用就和jq完全不一样了,promise链式调用的特点:
    这里写图片描述

    这里写图片描述

    关于Promise的实现,我做了一个简单的promise:

    function easyPromise(fn) {
        var that = this;
        this.then = function (cb) {
            that.cb = cb;
          }
        this.resolve = function (data) {
            that.cb(data);
        }
    
        fn(this.resolve);
    }
    
    new easyPromise((resolve)=>{
        setTimeout( ()=> {
            resolve("延迟执行");
        },1000);
    }).then( (data) => {
        console.log(data);
    } )
    

    可以简写成

    // 定义一个要传给 promise 的函数,它接收一个函数(resolve)作为参数。
    // resolve 的作用是在合适的时间,通知 promise 应该要执行 then 里面的回调函数了。
    function promiseCallback (resolve) {
        setTimeout(() => {
           resolve("延时执行")
        }, 1000)
     }
     
     // 定义一个 要传给 then 的回调函数
     function thenCallback (data) {
         console.log(data)
     }
     
     // 实例化 promis,并分别传入对应的回调
     new easyPromise(promiseCallback)
     .then(thenCallback)
    

    1.先通过 then 把 thenCallback 存起来
    2.执行 promise 括号里的函数,并把事先定义好的 resolve 函数作为参数传给他

    fn(this.resolve)
    

    3.执行 promiseCallback 我们的逻辑就跳到 promiseCallback 函数内部去

    setTimeout(() => {
      resolve("延时执行")
    }, 1000)
    

    逻辑很简单,就是等待1秒后,执行 resolve 函数, 这个 resolve 哪来的呢?
    fn(this.resolve) -> promiseCallback (resolve) -> resolve

    4.执行 resolve 我们的逻辑就跳到 resolve 函数内部去

    that.cb(data)
    

    这个 that.cb 又是哪来的呢? 就是我们第一步保存的 then括号里面的回调函数,也就是 thenCallback

    console.log(data)
    

    所以就在1秒后输出 延时执行

    关于this

    this是js函数运行过程中的一个对象,环境对象。

    诶,自己总结的发现还是没阮老师的好。。所以还是看阮老师的吧,链接

  • 相关阅读:
    May 1 2017 Week 18 Monday
    April 30 2017 Week 18 Sunday
    April 29 2017 Week 17 Saturday
    April 28 2017 Week 17 Friday
    April 27 2017 Week 17 Thursday
    April 26 2017 Week 17 Wednesday
    【2017-07-04】Qt信号与槽深入理解之一:信号与槽的连接方式
    April 25 2017 Week 17 Tuesday
    April 24 2017 Week 17 Monday
    为什么丑陋的UI界面却能创造良好的用户体验?
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/9484903.html
Copyright © 2011-2022 走看看