分分鐘讓你解決,異步加載致使的異常數據

async-demo

關於一些處理異步請求的方法javascript

一、常見的JavaScript場景

  • 1.setInterval setTimeout這種計時器函數。html

  • 2.http請求例如vue-resourcefetchaxios。等請求方式。vue

二、常見的現象

  • 一、不能按照要求獲得結果java

  • 二、想要獲得結果,須要運用傳統的回調函數,表示很是的繁瑣。ios

function A(){
       setTimeout(B(),200);
        C();
 
}
A()
執行順序A->B->C

var c="";
Vue.http.jsonp('http://ipinfo.io/json').then(function(data) {
    self.weatherData.city = data.data.city;
    self.weatherData.country = data.data.country;
    c= data.data.city;
    });
c=?

三、主要的方法

  • 一、回調函數git

f1();
f2();

function f1(callback){
    setTimeout(function () {
      // f1的任務代碼
      callback();
    }, 1000);
  }

f1(f2);
  • 二、事件監聽github

f1.on('done', f2);
function f1(){
    setTimeout(function () {
      // f1的任務代碼
      f1.trigger('done');
    }, 1000);
 }
f1();
  • 三、發佈/訂閱json

jQuery.subscribe("done", f2);
function f1(){
    setTimeout(function () {
      // f1的任務代碼
      jQuery.publish("done");
    }, 1000);
}
f1();
jQuery.unsubscribe("done", f2);
  • 四、Promises對象axios

f1().then(f2);
function f1(){
    var dfd = $.Deferred();
    setTimeout(function () {
      // f1的任務代碼
      dfd.resolve();
    }, 500);
    return dfd.promise;
 }
f1();

前面四種都是比較傳統,同時還依賴jQuery,用的時候擴展性和方便都不帶勁具體代碼請查看這裏,建議使用如下3中方式。api

  • 五、ES6 promise

  • 六、ES6 generator

  • 七、ES7 async和wait

四、實戰項目

  • 一、Promise

var promise = null;//定義全局變量
//new 一個Promise對象
promise = new Promise(function(resolve, reject) {
 Vue.http.jsonp('http://ipinfo.io/json').then(function(data)
      {
            if (data != null) {
                resolve(data);
            } else {
                reject("fail");
            }
        self.weatherData.city = data.data.city;
        self.weatherData.country = data.data.country;
        });
    })
//利用promise進行鏈式傳遞
 promise.then(function(data) {
                        var city = data.data.city+data.data.country;
                        Vue.http.jsonp(api + city + units + appid).then(function(data) {
                            that.weatherShow(data);
                        });
                    })

總結

  • 一、promise主要解決回調地獄問題

  • 二、使得本來的多層級的嵌套代碼,變成了鏈式調用

  • 三、讓代碼更清晰,減小嵌套數

  • 缺點:Promise 的最大問題是代碼冗餘,原來的任務被Promise 包裝了一下,無論什麼操做,一眼看去都是一堆 then,原來的語義變得很不清楚。
    demo

Paste_Image.png

  • 二、generatoryield

getLoc: function() {
                    var that = this;
                    Vue.http.jsonp('http://ipinfo.io/json').then(function(data) {
                        self.weatherData.city = data.data.city;
                        self.weatherData.country = data.data.country;
                        it.next(data.data);
                        //重點4
                    });
                },
                getCurrent: function(data) {
                    var that = this;
                    var api = "http://api.openweathermap.org/data/2.5/weather?q=";
                    var units = "&units=metric";
                    var appid = "&APPID=061f24cf3cde2f60644a8240302983f2"
                    var cb = "&callback=JSON_CALLBACK";
                    var city = data.city + ',' + data.country;
                    Vue.http.jsonp(api + city + units + appid).then(function(data) {
                        it.next(data);//重點4
                    });
//重點1
function* generator() {
                var data = yield object.getLoc();
                data = yield object.getCurrent(data);
                yield object.weatherShow(data);
            }
            var it = generator();//重點2
            it.next();//重點3

總結

  • 一、利用迭代器原理,解決異步問題

  • 二、讓代碼更清晰,減小嵌套數。

  • 缺點:雖然 Generator 函數將異步操做表示得很簡潔,可是流程管理卻不方便
    demo

  • 三、asyncwait

getLoc: function() {
                    var that = this;
                    return new Promise(function(resolve, reject) {
                        Vue.http.jsonp('http://ipinfo.io/json').then(function(data) {
                            self.weatherData.city = data.data.city;
                            self.weatherData.country = data.data.country;
                            resolve(data.data);
                        });
                    })
                },
                getCurrent: function(data) {
                    var that = this;
                    var api = "http://api.openweathermap.org/data/2.5/weather?q=";
                    var units = "&units=metric";
                    var appid = "&APPID=061f24cf3cde2f60644a8240302983f2"
                    var cb = "&callback=JSON_CALLBACK";
                    var city = data.city + ',' + data.country;
                    return new Promise(function(resolve, reject) {
                        Vue.http.jsonp(api + city + units + appid).then(function(data) {
                            resolve(data);
                            // that.weatherShow(data);
                        });
                    });

                },
//重點1
 async function test() {
                const v1 = await object.getLoc();
                const v2 = await object.getCurrent(v1);
                const v3 = await object.weatherShow(v2);
            }
            test();

總結

  • 一、解決異步問題

  • 二、await後面不能再跟thunk函數,而必須跟一個Promise對象(所以,Promise纔是異步的終極解決方案和將來)。跟其餘類型的數據也OK,可是會直接同步執行,而不是異步。

  • 三、讓代碼更清晰,減小嵌套數。

  • 四、代碼的易讀性來將,async-await更加易讀簡介,也更加符合代碼的語意。並且還不用引用第三方庫,也無需學習Generator那一堆東西,使用成本很是低。
    demo

附上 github源代碼 若是以爲好就關注吧

相關文章
相關標籤/搜索