美文网首页
异步的发展

异步的发展

作者: 陈左夕 | 来源:发表于2018-03-23 23:25 被阅读0次

    发展过程

    • 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可以按照顺序执行
    罗里吧嗦了一堆,终于进入主题了,想来时间也不晚了,还是洗洗睡吧
    未完待续,这里有后续可看

    相关文章

      网友评论

          本文标题:异步的发展

          本文链接:https://www.haomeiwen.com/subject/fbrfcftx.html