zoukankan      html  css  js  c++  java
  • 链式调用

    以一个简单的例子为例,我们要实现一个链式的调用,例:

    Man('pcd').eat('lunch').eat('dinner')
    

    该方法简单,只需我们新建一个对象,将Man、eat作为对象的属性,每次调用时返回该对象变可以实现
    例:

    function _Man(name) {
    	console.log('I am ' + name);
    }
    
    _Man.prototype.eat = function(something) {
    	console.log('eat ' + something);
    	return this;
    }
    
    function Man(name) {
    	return new _Man(name);
    }
    
    Man('pcd').eat('lunch').eat('dinner');
    //I am pcd
    //eat lunch
    //eat dinner
    
    

    此时我们想改变一下,pcd不想吃完中饭后直接去吃晚饭,他想过5s之后再去吃晚饭

    Man('pcd').eat('lunch').wait(5000).eat('dinner');
    

    改变上面的例子

    function _Man(name) {
    	console.log('I am ' + name);
    }
    
    _Man.prototype.eat = function(something) {
    	console.log('eat ' + something);
    	return this;
    }
    
    _Man.prototype.wait = function(time) {
    	setTimeout(function() {
    		console.log('wait ' + time);
    	}, time);
    	return this;
    }
    
    function Man(name) {
    	return new _Man(name);
    }
    
    Man('pcd').eat('lunch').wait(5000).eat('dinner');
    //I am pcd
    //eat lunch
    //eat dinner
    //wait 5000
    

    输出的结果跟我们的预期不符,我们需要先"wait 5000"后再"ear dinner";当然你会想我们可以再执行完定时器之后再回到this对象就好了。如下

    function _Man(name) {
    	console.log('I am ' + name);
    }
    
    _Man.prototype.eat = function(something) {
    	console.log('eat ' + something);
    	return this;
    }
    
    _Man.prototype.wait = function(time) {
    	var _this = this;
    	setTimeout(function() {
    		console.log('wait ' + time);
    		return _this;
    	}, time);
    }
    
    function Man(name) {
    	return new _Man(name);
    }
    
    Man('pcd').eat('lunch').wait(5000).eat('dinner');
    //I am pcd
    //eat lunch
    //Cannot read property 'eat' of undefined
    

    但是却报了eat为undefined,因为我们在执行定时器操作相当于异步操作,而Man('pcd').eat('lunch').wait(5000).eat('dinner');中wait函数后的eat还需要继续执行,但此时的this还没有返回,故找不到eat的方法。所以我们需要换一种方式解决。
    首先,我们先执行链式调用的Man('pcd').eat('lunch').wait(5000).eat('dinner');但不实际操作该函数,只是将其存放在数组中,通过setTimeout执行异步操作,从数组中一个个去除执行变可以了,如下:

    function _Man(name) {
    	console.log('I am ' + name);
    	var _this = this;
    	this.funcArr = [];
    	setTimeout(function() {
    		_this.next();
    	})
    }
    
    _Man.prototype.next = function() {
    	var fn = this.funcArr.shift();
    	fn&&fn();
    }
    
    _Man.prototype.eat = function(something) {
    	var _this = this;
    	var func = function(something) {
    		console.log('eat ' + something);
    		_this.next()
    	}
    	this.funcArr.push(func);
    	return this;
    }
    
    _Man.prototype.wait = function(time) {
    	var _this = this;
    	var func = function(time) {
    		setTimeout(function() {
    			console.log('wait ' + time);
    			_this.next();
    		}, time);
    	}
    	this.funcArr.push(func);
    	return this;
    }
    
    function Man(name) {
    	return new _Man(name);
    }
    
    Man('pcd').eat('lunch').wait(5000).eat('dinner');
    //I am pcd
    //eat undefined
    //wait undefined
    //eat undefined
    

    此时你会发现函数虽然放入数组并一个个执行了,但函数的参数并没有传入进去。此时我们便需要使用高大上的闭包存储变量了。

    function _Man(name) {
    	console.log('I am ' + name);
    	var _this = this;
    	this.funcArr = [];
    	setTimeout(function() {
    		_this.next();
    	})
    }
    
    _Man.prototype.next = function() {
    	var fn = this.funcArr.shift();
    	fn&&fn();
    }
    
    _Man.prototype.eat = function(something) {
    	var _this = this;
    	var func = (function(something) {
    		return function() {
    			console.log('eat ' + something);
    			_this.next();
    		}
    	})(something);
    	this.funcArr.push(func);
    	return this;
    }
    
    _Man.prototype.wait = function(time) {
    	var _this = this;
    	var func = (function(time) {
    		return function() {
    			setTimeout(function() {
    				console.log('wait ' + time);
    				_this.next();
    			}, time);
    		}
    	})(time);
    	this.funcArr.push(func);
    	return this;
    }
    
    function Man(name) {
    	return new _Man(name);
    }
    
    Man('pcd').eat('lunch').wait(5000).eat('dinner');
    //I am pcd
    //eat lunch
    //wait 5000
    //eat dinner
    

    大功告成。。。

  • 相关阅读:
    C#连接各种数据库的方法
    C#中MDI窗体的一些设置
    Winform子窗体刷新父窗体
    MDI窗体应用程序
    C# 窗体间传值方法大汇总
    mdi父窗体如何向子窗体发送数据
    DataGridView 清空原数据
    js call回调的this指向问题
    sass进阶 @if @else if @else @for循环
    sass的加减乘除
  • 原文地址:https://www.cnblogs.com/pcd12321/p/6327436.html
Copyright © 2011-2022 走看看