zoukankan      html  css  js  c++  java
  • javascript异步编程的几种方法

    目前工作中用的比较多的异步模式编程有如下几种方法

    一 回调函数

    这是异步编程最基本的方法,假设有两个函数f1和f2,后者等待前者的执行结果

    f1();
    f2();

    如果f1是一个很耗时的任务,可以考虑改写f1,把f2写成f1的回调函数

    function f1(callback){
       setTimeout(function(){
           // f1的任务代码
          
           //执行回调函数
          callback()
        },1000)
    }

    执行代码就变成下面这样:

    f1(f2);//调用

    采用这种方式,我们把同步操作变成了异步操作,f1不会堵塞程序运行,相当于先执行程序的主要逻辑,将耗时的操作推迟执行

    具体例子:

    由于ajax请求是异步的,有时候我们需要得到ajax请求后的数据,再进行其他的操作,这个时候回调函数会帮我们解决这个问题,具体代码如下:

    import $ from 'jquery'
    function getData(callback){
      var url="http://xxx.com/activity/v1/homepage/index";
      var data={
          "cityId":110100,
          "type":"coupon"
      }
      $.ajax({
           url:url,
           type:'get',
           dataType:'jsonp',
           jsonp:'callback',
           data:data,
           success:function(resp){
            if(resp.status==200 && resp.data){
                var item = resp.data[0] && resp.data[0].coupon;
                if(callback){
                    callback(item) //执行回调函数
                }
            }
           },
           error:function(err){
                console.log("error")
           }
      })
    }
    
    function getItem(data){
        if(data){
            //得到数据进行处理
            var url = data.moreUrl;
            alert(url)
        }
    }
    
     getData(getItem) //调用

    二 发布/订阅 模式

    我们假定,存在一个"信号中心",某个任务执行完成,就向信号中心"发布"(publish)一个信号,其他任务可以向信号中心"订阅"(subscribe)这个信号,从而知道什么时候自己可以开始执行。这就叫做"发布/订阅模式"(publish-subscribe pattern),又称"观察者模式"(observer pattern)。

    这个模式有多种实现,下面采用的是Ben Alman的Tiny Pub/Sub,这是jQuery的一个插件。

    function PubSub(){
      this.handlers = {};
    }
    
    PubSub.prototype = {
      on:function(eventType,handler){
        var self = this;
        if(!(eventType in self.handlers)){
            self.handlers[eventType] = [];
        }
         self.handlers[eventType].push(handler);
          return this;
      },
      trigger:function(eventType){
        var self = this;
        var handlerArgs = Array.prototype.slice.call(arguments,1);
        for(var i=0;i<self.handlers[eventType].length;i++){
          self.handlers[eventType][i].apply(self,handlerArgs)
        }
        return self;
      }
    }

    具体调用:

    var pubsub=new PubSub();
    
    function getData(){
      var url="http://xxx.com/activity/v1/homepage/index";
      var data={
          "cityId":110100,
          "type":"coupon"
      }
      $.ajax({
           url:url,
           type:'get',
           dataType:'jsonp',
           jsonp:'callback',
           data:data,
           success:function(resp){
            if(resp.status==200 && resp.data){
                var item = resp.data[0] && resp.data[0].coupon;
                pubsub.trigger('done',item) //发布事件
            }
           },
           error:function(err){
                console.log("error")
           }
      })
    }
    
    //订阅事件
    pubsub.on('done',function(data){
      getItem(data)
    })
    
    function getItem(data){
      alert('start')
      console.log('data='+data)
        if(data){
            //得到数据进行处理
            var url = data.moreUrl;
            alert(url)
        }
    }
    
     getData() //调用

    三 Promise对象

    Promise 对象是CommonJS工作组提出的一种规范,目的是为异步编程提供统一接口

    结合es7提供的async和await使用,代码如下:

    import $ from 'jquery'
    function getData(){
      return new Promise((resolve,reject) => {
         var url="http://xxx.com/activity/v1/homepage/index";
         var data={
            "cityId":110100,
            "type":"coupon"
          }
          $.ajax({
             url:url,
             type:'get',
             dataType:'jsonp',
             jsonp:'callback',
             data:data,
             success:function(resp){
                if(resp.status==200 && resp.data){
                  var item = resp.data[0] && resp.data[0].coupon;
                   resolve(item)
                }
             },
             error:function(err){
               reject("error")
             }
          })
      })
    }
    
    function getItem(data){
        if(data){
            //得到数据进行处理
            var url = data.moreUrl;
            alert(url)
        }
    }
    
    const testAsync = async () => {
      var data = await getData();
      getItem(data); 
    }
    
    //调用
    testAsync();

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

  • 相关阅读:
    水晶苍蝇拍:从“航空母舰”看企业竞争优势分析 (2010-05-11 11:48:38)
    水晶苍蝇拍:为何设定了安全边际后还吃大跌?
    水晶苍蝇拍:“低风险,高不确定性”的启示 (2010-04-24 22:02:13)
    水晶苍蝇拍:我这样看投资的安全性 (2009-08-27 20:08:53)
    水晶苍蝇拍:不同企业的估值差告诉我们什么? (2010-04-21 20:56:19)
    水晶苍蝇拍:估值,像雾像雨又像风 (2010-03-15 10:44:16)
    水晶苍蝇拍:长持的简单逻辑 (2009-05-25 18:08:43)
    Android中RelativeLayout各个属性的含义
    有道词典 Andriod 版本数据格式分析
    电驴提示“该内容尚未提供权利证明,无法提供下载”之解决办法详解
  • 原文地址:https://www.cnblogs.com/alice626/p/6475026.html
Copyright © 2011-2022 走看看