发展过程
- callback -> promise -> genrator + co -> async + await(语法糖)
异步是不支持try/catch的,try/catch只在同步中使用
node支持异步
// 1.txt -> 周杰伦
// 2.txt -> 七里香
// node里内置的fs方法
const fs = require('fs');
fs.readFile('1.txt', 'utf8', function (err, data) {
fs.readFile(data, 'utf8', function (err, data) {
console.log(data);
});
});
高阶函数
- 定义: 函数可以作为参数or函数可以作为返回值
来实现个判断数据类型的isType函数
function isType(type, value) {
return Object.prototype.toString.call(value) === `[object ${type}]`;
}
console.log(isType('String', 'hello')); // true
console.log(isType('Array', ['hi', 1, 2])); // true
console.log(isType('Function', function (){}); // true
上面的isType函数虽然可以实现数据类型的判断,但是每次都要传递多余的参数,这样写起来很麻烦,其实下面还有更好的方法来减少参数
改良后的isType如下:
// 批量生产函数
function isType(type) { // 偏函数 先预置进去
return function(value) {
return Object.prototype.toString.call(value) === `[object ${type}]`;
}
}
const isArray = isType('Array'); // 判断数组
const isString = isType('String'); // 判断字符串
console.log(isArray([222])); // true
像批量生产函数的这种实现,还有一种就是预置函数,预置函数的实现原理很简单,当达到条件时再执行回调函数,像lodash里的after方法一样
function after(time, cb) {
return function() {
if (--time === 0) {
cb();
}
}
}
// 举个栗子吧,吃饭的时候,我很能吃,吃了三碗才能吃饱
let eat = after(3, function() {
console.log('吃饱了');
});
eat();
eat();
eat();
// 只有执行三次吃的函数才会触发‘吃饱了’
前面说了好多别的,有点跑题了,继续回来说异步的事
我现在还是有两个文件,我要用fs去读取,然后异步的问题就来了,我怎么知道哪个先读完,哪个后读完。
好吧,其实我也不关心,我关心的是我要怎么拿到这两个文件里的数据
说下我的思路吧
一开始想直接放个数组来存取每次读到的数据,但这个放在同步情况下没问题
异步就不行了,我毕竟不知道哪个先读取完,这个过程是无法判断的
于是乎想到了个最简单的方法,得利用函数了,把数据当做参数传过去
// 写一个输出数据的函数
let arr = [];
function out(data) {
arr.push(data);
if (arr.length === 2) {
console.log(arr); // ['周杰伦', '七里香']
}
}
fs.readFile('1.txt', 'utf8', function(err, data) {
out(data);
});
fs.readFile('2.txt', 'utf8', function(err, data) {
out(data);
});
以上代码确实实现了把读取的数据都拿到了
But还是有些小缺陷,out里面的数字2是写死的
如果又多了一个文件读取,那就得改成3了,这很不够酷
那么,怎样改比较好呢,还记得上面实现的after函数吧
现在来看看它的用处吧
// 用after函数去改造一下out函数
let out = after(2, function(arr) {
console.log(arr);
});
function after(time, cb) {
// result被引用了,形成了闭包,不会被回收掉
let result = [];
return function(data) {
result.push(data);
if (--time === 0) {
cb(result); // 可以缓存函数,当到达条件时执行
}
}
}
fs.readFile('1.txt', 'utf8', function(err, data) { out(data); });
fs.readFile('2.txt', 'utf8', function(err, data) { out(data); });
虽然after方法已经很好了,但是我们不能每次处理异步请求的时候,都手写一遍after函数,这不科学,不合理
SO因此我们用上了promise
promise
从实际开发中,promise解决了回调地狱的问题,不会导致难以维护
then可以按照顺序执行
罗里吧嗦了一堆,终于进入主题了,想来时间也不晚了,还是洗洗睡吧
未完待续,这里有后续可看
网友评论