您的位置:首页 > 其它

异步加载导致的异常数据

2017-03-16 09:00 204 查看


async-demo

https://segmentfault.com/a/1190000008704308

关于一些处理异步请求的方法


1、常见的JavaScript场景

1.
setInterval
 
setTimeout
这种计时器函数。

2.http请求例如
vue-resource
fetch
axios
。等请求方式。


2、常见的现象

1、不能按照要求得到结果

2、想要得到结果,需要运用传统的回调函数,表示非常的繁琐。

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=?


3、主要的方法

1、回调函数

f1();
f2();

function f1(callback){
    setTimeout(function () {
      // f1的任务代码
      callback();
    }, 1000);
  }

f1(f2);


2、事件监听

f1.on('done', f2);
function f1(){
    setTimeout(function () {
      // f1的任务代码
      f1.trigger('done');
    }, 1000);
 }
f1();


3、发布/订阅

jQuery.subscribe("done", f2);
function f1(){
    setTimeout(function () {
      // f1的任务代码
      jQuery.publish("done");
    }, 1000);
}
f1();
jQuery.unsubscribe("done", f2);


4、
Promises
对象

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


前面四种都是比较传统,同时还依赖
jQuery
,用的时候扩展性和方便都不带劲具体代码请查看这里,建议使用以下3中方式。

5、
ES6 promise


6、
ES6 generator


7、
ES7 async和wait



4、实战项目

1、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);
});
})


总结

1、
promise
主要解决回调地狱问题

2、使得原本的多层级的嵌套代码,变成了链式调用

3、让代码更清晰,减少嵌套数

缺点:
Promise
 的最大问题是代码冗余,原来的任务被Promise
包装了一下,不管什么操作,一眼看去都是一堆 then,原来的语义变得很不清楚。
demo



2、
generator
yield


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


总结

1、利用迭代器原理,解决异步问题

2、让代码更清晰,减少嵌套数。

缺点:虽然
 Generator
 函数将异步操作表示得很简洁,但是流程管理却不方便
demo

3、
async
wait


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();


总结

1、解决异步问题

2、
await
后面不能再跟thunk函数,而必须跟一个Promise对象(因此,Promise才是异步的终极解决方案和未来)。跟其他类型的数据也OK,但是会直接同步执行,而不是异步。

3、让代码更清晰,减少嵌套数。

4、代码的易读性来将,
async-await
更加易读简介,也更加符合代码的语意。而且还不用引用第三方库,也无需学习
Generator
那一堆东西,使用成本非常低。
demo

附上 github源代码 如果觉得好就关注吧
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: