Javascript的优势之一是其如何处理异步代码。异步代码会被放入一个事件队列,等到所有其他代码执行后才进行,而不会阻塞线程。
但是前端在写交互的时候,可能需要对数据进行同步的操作
var data;
$.ajax({
url: "some/url/1",
success: function( data ) {
// 放在jquery指定的success函数里面可以保证异步请求完成
console.log( data );
}
})
// 这里并不能获取数据 ajax异步请求还未完成
console.log( data );
解决办法:
1、ajax嵌套
$.ajax({
url: "some/url/1",
success: function( params ) {
// JQ success里的异步请求已完成,数据已得到,可通过嵌套进行调用
$.ajax({
data: {
params: params
}
})
}
})
2、改为同步请求(async: false),使用同步请求的缺点就是一旦这个接口长时间未返回数据,下面的js也不会执行。
var par = null
$.ajax({
url: "some/url/1",
async: false,
success: function( params ) {
// JQ success里的异步请求已完成,数据已得到,可通过嵌套进行调用
par = params
}
})
//由于是同步请求,这里打印出来的是ajax请求回来的数据,而不是null
console.log(par)
3、
Promise(ES6)--处理异步
function test() {
return new Promise(function (resolve, reject) {
self.axios.get(url).then(function (res) {
resolve(res)
}).catch(function (err) {
resolve(err)
})
})
}
test().then(data=>{
console.log(data)
}).catch(err=>{
console.log(err)
})
4、
ES7的Async/Await--处理异步
var sleep = function (time) {
return new Promise(function(resolve, reject) { // 返回一个promise对象
setTimeout(function() {
resolve();
}, time)
})
};
var start = async function() {
console.log('开始');
await sleep(3000); // 等待异步过程完成再往下执行
console.log('结束');
}
start();
// 控制台先输出start,稍等3秒后,输出了end。
基本规则
async 表示这是一个async(异步)函数,await只能用在这个函数里面。
await 表示在这里等待promise返回结果了,再继续执行。
await 后面跟着的应该是一个promise对象(当然,其他返回值也没关系,只是会立即执行,不过那样就没有意义了…)
获得返回值
await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// 返回 ‘ok’
resolve('ok');
}, time);
})
};
var start = async function () {
let result = await sleep(3000);
console.log(result); // 收到 ‘ok’
};
// 获取异步结果
let sleep = function (time) {
return new Promise(function(resolve, reject){
setTimeout(function() {
resolve('异步返回结果');
}, time)
});
};
let start = async function() {
let result = await sleep('3000');
console.log(result);
};
start(); // 3秒后输出 '异步返回结果'
// ** 捕获错误
var asyncFn = function (time) {
return new Promise((resolve, reject) => {
setTimeout(function() {
reject('异步出了问题');
}, time)
});
};
var start = async function() {
console.log('开始');
let result = await asyncFn(3000); // 返回了一个错误,不会往下执行了
console.log(result);
console.log('结束');
};
// 开始
// (node:2200) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): 异步出了问题
// (node:2200) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
// 既然.then(..)不用写了,那么.catch(..)也不用写,可以直接用标准的try catch语法捕捉错误。
var start = async function() {
try{
console.log('开始');
let result = await asyncFn(3000); // 返回了一个错误,不会往下执行了
console.log(result);
console.log('结束');
} catch(err) { //出了错误
console.log(err)
}
};
// 开始
// 异步出了问题
start();