懒是一个程序员的好习惯,没错就是这样。
假设使用 JQuery
来写一个 Promise
,有以下 2
个条件:
ajax $.ajax
那么这个方法大概是这样的:
var getData = function (data1, data2){
var defer = $.Deferred();
$.get('http://xxx.xxx.xxx?data1=' + data1 + '&data2=' + data2)
.then(function(result){
defer.resolve(result);
})
return defer.promise();
}
getData().then(function(result){
console.log(result)
})
感觉还是挺简洁干净的,但对于每天要写 10
多个 ajax
的我来说,这在我脑里就是这样:
while(true){
var defer = $.Deferred();
defer.resolve(result);
return defer.promise();
}
能不能把这 3
行给干掉啊,这样我就能少些 n * 3
行代码了。我也不想显示的控制返回,需要我脑子参与的应该就仅仅是写个逻辑。
让函数返回函数,内层函数声明 Promise
函数,并在最后返回该 Promise
对象。
需要执行的函数以参数的形式传入到外层函数,在内层函数中进行调用,将 Promise
修改状态的两个函数 resolve
和 reject
以参数形式传入以参数形式传入的函数 func
。
感觉有点绕,直接上代码吧。
首先不考虑执行的函数需要传递传参的情况,这种情况比较简单。
function q(func){
return function(){
var defer = $.Deferred();
func && func(defer.resolve, defer.reject);
return defer.promise();
}
}
然后 getData 就变成这样了:
var getData = q(function (resolve, reject){
$.get('http://xxx.xxx.xxx')
.then(function(result){
resolve(result);
})
})
getData().then(function(result){
console.log(result)
})
是不是有一种酣畅淋漓的感觉,光写主要的代码逻辑就好了,函数返回的就是 Promise
。
接下来考虑到 getData
可能需要传入参数,就如同开头说的那样,而且我们要实现的是通用的函数,所以我们不知道实际传入的参数的个数,但是实现起来需要用到 apply
和 arguments
这两个在 js
中不太被了解的东西。
思考后,撸出了这样的代码,供大家参考:
function q(func){
return function(){
var args = Array.prototype.slice.call(arguments);
var defer = $.Deferred();
args.push(defer.resolve, defer.reject);
func && func.apply(undefined, args);
return defer.promise();
}
}
那么 getData
就可以这样了:
var getData = q(function (data1, data2, resolve, reject){
$.get('http://xxx.xxx.xxx?data1=' + data1 + '&data2=' + data2)
.then(function(result){
resolve(result);
})
})
getData().then(function(result){
console.log(result);
})
对于其他的不同实现的 Promise
比如说 $q
、 Q
、原生实现的 Promise
也是一样的,
原生的 Promise
:
function q(func){
return function(){
var args = Array.prototype.slice.call(arguments);
return new Promise(function(resolve, reject) {
args.push(resolve, reject);
func && func.apply(undefined, args);
});
}
}
angular
中的 $q
:
function q(func){
return function(){
var args = Array.prototype.slice.call(arguments);
var defer = $q.defer();
args.push(defer.resolve, defer.reject);
func && func.apply(undefined, args);
return defer.promise;
}
}
无论多少个参数都没用问题,突然感觉如沐春风啊,不多说了我要把剩下来的时间拿去睡觉拿去 happy 了。
最后强调一遍: 懒是一个程序员的好习惯,没错就是这样。