异步的发展过程

原文: 异步的发展过程

 

发展过程

  • callback -> promise -> generator + 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函数,这不科学,不合理

因此我们用上了promise

promise

从实际开发中,promise解决了回调地狱的问题,不会导致难以维护

then可以按照顺序执行

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值