async与await的原理
async与await的原理
异步函数,也称为async/await(语法关键字),是ES8规范新增的。这个特性从行为和语法上都增强了JavaScript,能够以同步的方式执行异步代码。最明显就是解决了“回调地狱”的问题。
let data = await new Promise((res, rej) => {
$.ajax({
url: 'getUserById',
data: {
id: 1
},
success(data) {
res(data);
}
});
});
data = await new Promise((res, rej) => {
$.ajax({
url: 'getRightsByRoleId',
data: {
id: data.id
},
success(data) {
res(data);
}
});
});
data = await new Promise((res, rej) => {
$.ajax({
url: 'getPagesByRrights',
data: {
rights: data.rights
},
success() {
console.log('终于获取完了');
}
});
});
async关键字用于声明异步函数。这个关键字可以用在函数声明、函数表达式、箭头函数和方法上。
async function foo() {}
let bar = async function() {};
let baz = async () => {};
class Qux {
async qux() {}
}
await因为异步函数主要针对不会马上完成的任务,所以自然需要一种暂停和恢复执行的能力。使用await关键字可以暂停异步函数代码的执行,等待Promise执行完成。
let p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 3));
p.then(console.log); //只是通过回调通知接收了结果,并不知道何时调用完成,所以后续的操作要放在回调函数中
console.log(await p); //使用await就得等待Promise执行完成才能进行下一步
console.log('上一次的Promise完成了,可以继续接下来的事了');
函数里出现await则必须有async。
async function foo() {
await Promise.resolve(); //合法
}
function foo() {
await Promise.resolve(); //非法
}
下面我们用一段代码来给大家更加直观的理解
async函数会返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的代码。
function getNum(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(num + 1)
}, 1000)
})
}
debugger
const func = async () => {
const f1 = await getNum(1)
const f2 = await getNum(f1)
// 输出3
}
func()
就拿上面的代码来说,回调函数中没有赋值,就不会执行,继续向下查找,在f1中找到getNum,但是f1中有await,就会先返回,执行上面的代码,此时的f1已经num+1,就会重新赋值为2,一步操作完成,继续执行后面的代码,在f2中再次找到getNum赋值为f1,也就是赋值为2,遇见await就会继续返回,num再次+1,也加是3,打印出来也就是3了。