最近被问到这个问题,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都会跳过,只有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函数运行过程中的一个对象,环境对象。
诶,自己总结的发现还是没阮老师的好。。所以还是看阮老师的吧,链接
jQuery的链式调用原理,Promise的链式调用,this的问题
原文地址:https://www.cnblogs.com/zhangmingzhao/p/9484903.html