• Javascript异步编程



    1、什么是异步(Asynchronous)编程?

        相对于同步(Synchronous)而言,异步就是后一个任务不需要等待前一个任务结束就执行,而前一个任务结束以后执行回调函数。

        最常见的异步编程有setTimeout函数、 ajax请求等。

        如:

            for (var i = 1; i <= 3; i++) {
                setTimeout(function(){
                    console.log("#",i);
                }, 0);
                console.log("*",i);
            };

        输出的结果是:*1 *2 *3 #4 #4 #4

        涉及到的知识点: 异步、闭包、作用域

        setTimeout是一个注册事件,在主程序运行结束前,是不会调用的。

        就像为某个div绑定一个点击事件一样,在没点击之前,这个事件是不会被触发的。

        这就是一个常见的异步编程的例子。


    2、异步编程的方法

        Ⅰ、回调函数

            假设有 f1(); f2(); 两个函数,其中f2()在等待f1()的执行结果。

            function f1(f2){
                setTimeout(function(){
                  f2();
                }, 1000);
              }

            代码执行顺序:f1(f2);

            优点:f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行
            缺点:不利于代码的阅读和维护,各个部分之间高度耦合(Coupling),而且每个任务只能指定一个回调函数
                
        Ⅱ、事件监听

            f1.on('done', f2);//jQuery写法,当f1发生done事件,就执行f2

            function f1(){
            setTimeout(function () {
              f1.trigger('done');//执行完成后,立即触发done事件
            }, 1000);
          }

            优点:可以绑定多个事件,每个事件可以指定多个回调函数,而且可以"去耦合"(Decoupling),有利于实现模块化
            缺点:整个程序都要变成事件驱动型,运行流程会变得很不清晰


        Ⅲ、发布/订阅

            jQuery.subscribe("done", f2);//f2向jQuery订阅"done"信号

            function f1(){
           setTimeout(function () {
             jQuery.publish("done");//f1执行完成后,向jQuery发布"done"信号,从而引发f2的执行
           }, 1000);
         }


        Ⅳ、Promises对象   

            它的思想是,每一个异步任务返回一个Promise对象,该对象有一个then方法,允许指定回调函数。比如,f1的回调函数f2,可以写成:

            f1().then(f2);

            对f1进行如下改写:

            function f1(){
           var dfd = $.Deferred();
           setTimeout(function () {
             dfd.resolve();
           }, 500);
           return dfd.promise;
         }

            优点:回调函数变成了链式写法,程序的流程可以看得很清楚,可以指定多个回调函数,如:

                 f1().then(f2).then(f3);
                 f1().then(f2).fail(f3);

            缺点:编写和理解,都相对比较难    

    附几个概念:

    一、事件

        事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。

    二、注册事件
        
        注册事件分为属性注册和方法注册。

        属性注册:1.内嵌在DOM结构里的属性赋值

                    HTML: <button onclick="sayHello()">点击</button>

                      JS: function sayHello() {
                                 console.log('hello')
                          }

                2.通过JS来指定元素对象的属性赋值

                    document.body.onclick = function (e) {
                        alert("为body注册一个点击事件");
                    };

        方法注册:1.通过addEventListener()方法注册

                    说明:在JS中,window、document、HtmlElement等对象可以通过addEventListener()方法注册事件的处理程序。

                    语法:EventTarget.addEventListener(eventName, eventHandler, |useCapture )

                    参数:

                        ①eventName {string} :所要注册的事件名称,不区分大小写。此名称不需要像注册事件属性那样前缀加上"on"。如注册鼠标点击事件,写为click。

                        ②eventHandler {function | function Object} :函数或者函数对象。事件触发时所需要执行的函数;当使用函数对象多次注册同一事件时,只当注册一遍。

                        ③useCapture {boolean} 可选 :是否处于捕获阶段,默认为false。

                多次注册:addEventListener()方法能为同一个对象的同一事件注册多次。当发生此事件时,注册的处理事件程序将按照注册先后顺序执行。

                   注意:

                        ①IE9之前的IE的不支持此方法,可使用attachEvent()代替。

                        ②若使用相同的事件处理程序对象多次注册在同一个事件上,只算注册一次。

                  例:

                          document.body.addEventListener('click',function(e){
                             console.log('被点击一');
                        });
                                 
                        document.body.addEventListener('click',function(e){
                            console.log('被点击二');
                        });
                        
                        document.body.click(); // 输出: 被点击一 被点击二

                2.通过attachEvent()方法注册

                  说明:IE9之前的IE版本可通过此方法注册事件。

                  语法:EventTarget.attachEvent(eventName, eventHandler)
                  
                          ①eventName {string} :所要注册的事件名称,区分大小写。这里的名称跟事件属性一样,以"on"开头,后面跟着事件名称。如:onclick、onload。
                          
                          ②eventHandler {function | function Object} :函数或者函数对象。事件触发时所需要执行的函数;当使用函数对象多次注册同一事件时,可注册多次(addEventListener()方法只当注册一次)。
                  
              多次注册:attachEvent()方法能为同一个对象的同一事件注册多次。当触发此事件时,也会依次执行。

                 例:

                      function sayHellow(){
                       console.log('hello');
                    }
                    document.body.attachEvent('onclick',sayHellow);
                    document.body.attachEvent('onclick',sayHellow); // sayHellow第二次注册同一事件
                    document.body.click(); //输出2次sayHellow函数 :hello hello

    二、注销事件

            JS中,可调用removeEventListener()[注销addEventListener()] 和 detachEvent()[注销attachEvent()] 来注销元素的某个事件指定的处理程序,也可以给事件属性赋值null来注销此事件的所有绑定。
        
            1.removeEventListener(eventName, function Object)
            
            说明:注销通过addEventListener()注册的事件处理程序。
        
            语法:EventTarget.removeEventListener(eventName, eventHandlerObj)
            
            参数:
            
                ①eventName {string} :所要注销的事件名称,不区分大小写。此名称不需要像注册事件属性那样前缀加上"on"。如注册鼠标点击事件,写为click。
                
                ②eventHandlerObj {function Object} :函数对象。传入一个函数体是没有效果的。
        
            例:
                
                // 注销body click事件的sayHello函数
                document.body.removeEventListener('click',sayHello);

            2.detachEvent(eventName, function Object)

                说明:注销通过attachEvent()注册的事件处理程序。

                语法:EventTarget.detachEvent(eventName, eventHandlerObj)
                
                参数:
                
                    ①eventName {string} :所要注销的事件名称,区分大小写。这里的名称跟事件属性一样,以"on"开头,后面跟着事件名称。如:onclick、onload。
                    
                    ②eventHandlerObj {function Object} ::函数对象。传入一个函数体是没有效果的。


               例:

                       // 注销body click事件的sayHello函数
                       document.body.detachEvent('onclick', sayHello);

            3.取消事件

                给对象的事件属性赋值为null,可取消此事件的所有注册过的处理事件程序。

                例:

                    // onclick属性赋值为null,相当于注销了onclick事件
                    document.body.onclick=null;


    参考链接:http://www.ruanyifeng.com/blog/2012/12/asynchronous%EF%BC%BFjavascript.html
                    http://www.qdfuns.com/notes/17398/e8a1ce8f863e8b5abb530069b388a158/page/.html


        

  • 相关阅读:
    Brettle.Web.NeatUpload.dll支持的大文件上传
    流媒体服务器架设(转载)
    Photoshop用户必知必会的28个快捷键
    qq服务器Ip
    环球企业家:web2.0创业时代将终结
    真传丹道小周天功.txt
    如何解决管理工具MSC拒绝访问?
    photoshop快捷键大全
    利用ffmpeg把视频文件转换为flv文件
    编写高性能 Web 应用程序的 10 个技巧 转自微软资料
  • 原文地址:https://www.cnblogs.com/Man-Dream-Necessary/p/7374878.html
Copyright © 2020-2023  润新知