读书笔记-你不知道的JS中-promise

之前的笔记没保存没掉了,好气,重新写!

 

  填坑……

现在与将来

  在单个JS文件中,程序由许多块组成,这些块有的现在执行,有的将来执行,最常见的块单位是函数。

  程序中'将来'执行的部分并不一定在'现在'运行的部分执行完之后就立即执行,即异步执行将来的部分

    //异步请求data数据
    _.ajax('data');
    //打印data数据
    //一般情况下是打印不出来的
    console.log(data);

  一般的ajax请求都不是同步完成,如果要正确打印出data,最简单的方法是使用一个回调函数。

    //异步请求data数据
    _.ajax('url', function(data) {
        //取到数据并打印了出来
        console.log(data);
    });

  

异步控制台

  console对象并不是ECMA标准中的规定的,而是宿主环境(浏览器)添加到Javascript中的。

  因此,不同的浏览器和Javascript环境可以按照自己的意愿来实现,有时候这个会引起混淆。

  明确一点讲,有些情况下,某些浏览器的console.log(..)并不会把传入的内容立即输出。出现这种情况的主要原因是,在许多程序(not only Javascipt)中,I/O是非常低速的阻塞部分。所以,浏览器在后台异步处理控制器I/O能够提高性能,这时用户(开发也是)可能根本意识不到其发生。

  比如说:

    var obj = {
        index: 1
    };
    console.log(obj);
    obj.index++;

 

  

  严格来讲,obj.index++应该在打印之后才执行。但是,这段代码运行的时候,浏览器可能会认为需要把控制台I/O延迟到后台,这种情况下,++可能已经执行,因此会打印出index:2。

 

 

异步特殊情况

  

并发

  当两个异步请求都完成,才调用某个函数:

    var a, b;
    //只有当两个异步请求都完成时才会调用指定函数
    _.ajax('url1', function() {
        a = 1;
        if (a && b) {
            log();
        }
    });
    _.ajax('url2', function() {
        b = 1;
        if (a && b) {
            log();
        }
    });
    function log() {
        console.log(a + b);
    }

 

竞态

  第二种情况是只要有一个异步请求完成,就调用某个函数。

    var a;
    //有一个异步完成就会调用函数
    //第二个会被舍弃
    _.ajax('url1', function(data) {
        a = data;
        if (!a) {
            log();
        }
    });
    _.ajax('url2', function(data) {
        a = data;
        if (!a) {
            log();
        }
    });
    function log() {
        console.log(a);
    }

 

节流阀

  第三种情况是当请求到大量数据并需要进行处理时,可以通过异步来分批处理。

    var res = [];
    //节流阀函数
    function fn(data) {
        //每次处理1000个数据
        //书上未做这个判断 最后可能只有少量数据
        var chunk = data.length > 1000 ? data.splice(0, 1000) : data.splice(0, data.length);
        //处理数据 这里只是一个简单案例
        res = res.concat(chunk.map(function(val) {
            return val * 2;
        }));
        //是否仍有数据
        if (data.length > 0) {
            //异步处理
            setTimeout(function() {
                fn(data);
            }, 0);
        }
    }
    //ajax获取大量数据
    _.ajax('url', data);

  由于setTimeout是task事件(详细介绍可以看我的另外一个博客),所以会在主线程其他函数完事后插进去,保证页面流畅。

 

posted @ 2017-03-05 18:08  书生小龙  阅读(345)  评论(0编辑  收藏  举报