懒是一个程序员的好习惯,没错就是这样。
假设使用 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 了。
最后强调一遍: 懒是一个程序员的好习惯,没错就是这样。