javascript異步編程的幾種方法

目前工做中用的比較多的異步模式編程有以下幾種方法javascript

一 回調函數html

這是異步編程最基本的方法,假設有兩個函數f1和f2,後者等待前者的執行結果java

f1();
f2();

若是f1是一個很耗時的任務,能夠考慮改寫f1,把f2寫成f1的回調函數jquery

function f1(callback){
   setTimeout(function(){
       // f1的任務代碼
      
       //執行回調函數
      callback()
    },1000)
}

執行代碼就變成下面這樣:git

f1(f2);//調用

採用這種方式,咱們把同步操做變成了異步操做,f1不會堵塞程序運行,至關於先執行程序的主要邏輯,將耗時的操做推遲執行github

 

具體例子:ajax

因爲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) //調用

 

二 發佈/訂閱 模式json

咱們假定,存在一個"信號中心",某個任務執行完成,就向信號中心"發佈"(publish)一個信號,其餘任務能夠向信號中心"訂閱"(subscribe)這個信號,從而知道何時本身能夠開始執行。這就叫作"發佈/訂閱模式"(publish-subscribe pattern),又稱"觀察者模式"(observer pattern)。app

這個模式有多種實現,下面採用的是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

相關文章
相關標籤/搜索