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

  • 相关阅读:
    hdu1213
    [转]图论题集
    树剖题集
    【Python学习之旅】---线程的调用以及join方法
    【Python学习之旅】---自定制property
    【Python学习之旅】---描述符+装饰器应用
    【Python学习之旅】---类的装饰器
    【Python学习之旅】---描述符的应用
    【Python学习之旅】---上下文管理协议
    筱玛的迷阵探险(折半搜索+01字典树)
  • 原文地址:https://www.cnblogs.com/alice626/p/6475026.html
Copyright © 2011-2022 走看看