作为函数式编程来说,流程控制和函数库是必不可少的(应该吧)。
下面我们介绍两个常用的库。
lodash:完整的api请参阅,https://lodash.com/docs。这里我们只演示几个简单的例子。
安装
E:projectheron-lessondemo4>npm install lodash --save
1 var data1 = [1, 2, 3, 4, 5]; 2 var data2 = [ 3 {'user': 'barney', 'age': 36, 'active': true}, 4 {'user': 'fred', 'age': 40, 'active': false}, 5 {'user': 'pebbles', 'age': 1, 'active': true} 6 ]; 7 8 var _ = require('lodash'); 9 10 // find 只会返回一条数据,没有条件默认返回第一条 11 var r1 = _.find(data1); 12 console.log(r1); // -> 1 13 14 var r2 = _.find(data1, function (item) { 15 return item > 2; 16 }); 17 console.log(r2); // -> 3 18 19 var r3 = _.find(data2, function (item) { 20 return item.age > 20; 21 }); 22 console.log(r3); // -> { user: 'barney', age: 36, active: true } 23 24 25 // filter 返回所有满足条件的数据, 没有条件返回所有 26 var r4 = _.filter(data1); 27 console.log(r4); // -> [ 1, 2, 3, 4, 5 ] 28 29 var r5 = _.filter(data1, function (item) { 30 return item > 2; 31 }); 32 console.log(r5); // -> [ 3, 4, 5 ] 33 34 var r6 = _.filter(data2, function (item) { 35 return item.age > 20; 36 }); 37 console.log(r6); // -> [ { user: 'barney', age: 36, active: true }, { user: 'fred', age: 40, active: false } ]
我们演示了两个函数的用法,虚拟两个数组的数据,find函数会返回数组的一个元素,filter函数会返回多条。这里需要注意的是,即使filter一条数据也没有返回,也会返回空数组 []。
关于流程控制
我们来看这个例子,我们先模拟两个异步函数。
1 var firstFn = function (callback) { 2 setTimeout(function () { 3 return callback('This is first task.'); 4 }, 200); 5 }; 6 var secondFn = function (callback) { 7 setTimeout(function () { 8 return callback('This is second task.'); 9 }, 10); 10 };
接着看这样的写法。
1 firstFn(function (message) { 2 console.log(message); 3 }); 4 secondFn(function (message) { 5 console.log(message); 6 });
结果是
This is second task.
This is first task.
并没有按照代码顺序得到结果。这是因为异步任务延迟的不同造成的。可以将顺序的函数套到前面的回调里,来达到预期的结果。像这样
1 firstFn(function (message) { 2 console.log(message); 3 secondFn(function (message) { 4 console.log(message); 5 }); 6 });
然而,这样做的话,过多的嵌套,会让你的代码全是嵌套的括号,难以阅读和修改。
那么我们按照这个库来改进代码
E:projectheron-lessondemo4>npm install q --save
这是Promise标准的一个实现,我们可以编写Promise风格的代码了。
这种写法的每一步都返回Promise,所以我们之前的 fn(err, data) 风格的函数也得改成Promise风格的。
1 var firstFn = function () { 2 var defer = q.defer(); 3 setTimeout(function () { 4 console.log('This is first task.') 5 defer.resolve(); 6 }, 200); 7 return defer.promise; 8 }; 9 var secondFn = function () { 10 var defer = q.defer(); 11 setTimeout(function () { 12 console.log('This is second task.') 13 defer.resolve(); 14 }, 10); 15 return defer.promise; 16 }; 17 18 19 var q = require('q'); 20 21 firstFn() 22 .then(function () { 23 return secondFn(); 24 }) 25 .done(function () { 26 console.log('done') 27 });
得到结果
This is first task.
This is second task.
done
async风格的例子,请跳转至另外一篇 函数式编程第一步——流程控制
项目下载:demo4