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函数运行过程中的一个对象,环境对象。

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

  • 相关阅读:
    Codeforces Round #171 (Div. 2)
    ACdream 1079 郭式树
    HDOJ 1517 博弈论
    ACdream 1080 面面数
    博弈论 Nim 博弈
    Codeforces Round #172 (Div. 2)
    ACdream 1084 同心树
    STL bitset
    博弈论 bash博弈
    POJ 3261 后缀数组
  • 原文地址:https://www.cnblogs.com/zhangmingzhao/p/9484903.html
Copyright © 2011-2022 走看看