zoukankan      html  css  js  c++  java
  • 读书笔记-你不知道的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事件(详细介绍可以看我的另外一个博客),所以会在主线程其他函数完事后插进去,保证页面流畅。

  • 相关阅读:
    安全加固3-加固
    Centos7 64位 -- glibc-2.29 编译升级方法(已成功)
    Centos7 -- glibc 升级失败、意外删除、故意删除后的处理方法
    系统引导修复,grub2下的各种骚作
    linux 升级 5.0.2内核
    kvm虚拟化二: 字符界面管理及 无人值守安装
    kvm虚拟化一: 图形化的管理方式
    Linux rhel7 无线网络配置
    虚拟化简介
    requests模块使用二
  • 原文地址:https://www.cnblogs.com/QH-Jimmy/p/6506187.html
Copyright © 2011-2022 走看看