1.同步API与异步API
同步API:只有当前API执行完成后,才能继续执行下一个API;
异步API:当前API的执行不会阻塞后续代码的执行;
区别:
①同步API可以从返回值中拿到API执行的结果,但是异步API不可以。
②代码执行顺序不同
2.异步API都有哪些呢?
常见的异步调用有:定时任务(setTimeout),Ajax以及在此基础之上封装的axios等。
因为异步API的代码执行顺序不同,那么在异步API中,后面的代码需要依赖异步API的结果,那应该如何处理呢?
方式一:嵌套
把后面代码写到异步API的回调函数中,以Ajax请求举例如下:
$.ajax({
url: 'http://localhost:3000/data',
success: function(data) {
console.log(data)
$.ajax({
url: 'http://localhost:3000/data1',
success: function(data) {
console.log(data)
$.ajax({
url: 'http://localhost:3000/data2',
success: function(data) {
console.log(data)
}
});
}
});
}
});
此时的确可以解决异步的问题,当第一个请求成功之后会执行第二个请求,但是这种方式存在缺点:
1.影响性能,不易维护
2.如果嵌套层次过多,会形成回调地狱
方式二:Promise
Promise的基本用法:实例化Promise对象,构造函数中传递参数,该函数用于处理异步任务;resolve处理成功的情况,reject处理失败的情况,p.then获取处理的结果
var p = new Promise(function(resolve, reject) {
// 这里用于实现异步任务
setTimeout(function() {
var flag = true;
if (flag) {
// 正常情况
resolve("hello");
} else {
// 异常情况
reject("出错了");
}
}, 100);
});
p.then(
function(data) {
console.log(data);
},
function(info) {
console.log(info);
}
);
如果使用Promise发送多次Ajax请求,写法如下:
queryData('http://localhost:3000/data')
.then(function(data){
console.log(data)
return queryData('http://localhost:3000/data1');
})
.then(function(data){
console.log(data);
return queryData('http://localhost:3000/data2');
})
.then(function(data){
console.log(data)
});
使用Promise的好处:
①可以避免多层异步调用嵌套问题
②简洁的API,更加容易控制异步操作
缺点:写法有些复杂
方式三:async/await
async关键字用于函数上(async函数的返回值是Promise实例对象);
await关键字用于async函数当中(await promise 它可以暂停异步函数的执行,等待promise对象返回结果后再向下执行函数)
下面用setTimeout异步函数说一下async/await的基本用法:
data: {
test: ''
},
methods: {
async queryData() {
var ret = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("nihao");
}, 1000);
});
this.test = ret;
return ret
},
mounted(){
this.queryData().then(data => {
console.log(data);
})
}
这样在mounted函数中可以获取到queryData函数返回的ret值。这种方法还有一个变形如下(主要是mounted中发生了改变):
async mounted(){
// this.queryData().then(data => {
// console.log(data);
// })
await this.queryData()
console.log(this.test);
}
为什么会有这种变形呢?读者可以尝试一下,变形前在mounted中打印console.log(this.test);
是空,而变形后是nihao
。
使用async/await处理多个异步任务的方法如下:
async queryData() {
var ret = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("nihao");
}, 1000);
});
var res = await new Promise((resolve,reject) => {
resolve(ret + 'hpp')
})
this.test = res;
}
上述代码中,在第二个异步任务中也可以使用第一个异步任务的返回结果。
总结
由此,最终推荐使用async/await,应该可以满足读者处理异步函数的需要了。