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
    

    大功告成。。。

  • 相关阅读:
    关于JSON可能出现的错误,待更/todo
    mongoose的安装与使用(书签记录) 2017
    HTTP的学习记录3--HTTPS和HTTP
    HTTP的学习记录(二)头部
    HTTP(一)概述
    LeetCode 455. Assign Cookies
    LeetCode 453. Minimum Moves to Equal Array Elements
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 447. Number of Boomerangs
    LeetCode 416. Partition Equal Subset Sum
  • 原文地址:https://www.cnblogs.com/pcd12321/p/6327436.html
Copyright © 2011-2022 走看看