参考:https://www.cnblogs.com/zuobaiquan01/p/8477322.html
1. 何为同步,何为异步,为何要异步转同步
- 同步模式:Javascript语言的执行环境是"单线程",就是一次只能完成一件任务。如果有多个任务,就必须排队,前面一个任务完成,再执行后面一个任务,以此类推。(比如:JavaScript程序是从上到下依次按顺序执行,前提是不出现 异步模式 的情况下)
- 异步模式:按照同步模式执行的话,如果出现任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行,这种情况Javascript需要异步执行此任务,就是单独将其拿出来放在最后执行。(比如:setTimeout()方法、ajax请求、nodejs异步I/O、就是异步模式的,每一个任务都是单独执行,无先后排队一说
- 异步转同步:很多时候我们的异步任务是有依赖关系的,我们需要让其按照一定的先后顺序来执行(比如,ajax请求中,B请求需要A请求的结果作为参数去请求数据,我们就需要让A拿到结果后再去执行B请求)
2. 异步转同步的几种常见方式(等待执行)
- 函数嵌套的方式
在函数里执行函数
// fn1 先,fn2 后
function fn1() {
console.log('fn1');
setTimeout(() => {
fn2()
}, 1000);
}
function fn2() {
console.log('fn2');
}
fn1()
- callback 回调函数的方式
异步执行回调函数,回调函数就是作为变量传递给另外一个函数的函数,它在主体函数执行完之后执行
// fn1 先,fn2 后
function fn1(callback) {
console.log('fn1');
setTimeout(() => {
callback()
}, 1000);
}
function fn2() {
console.log('回调函数---fn2');
}
fn1(fn2)
- promise() 的方式
// fn1 先,fn2 后
function fn1() {
return new Promise((resolve, reject) => {
console.log('fn1');
setTimeout(() => {
resolve('fn2')
}, 1000);
})
}
function fn2(e) {
console.log(e);
}
fn1().then(res => {
fn2(res)
})
- async,await的方式()
async放在后执行函数前,await放在先执行函数前,最后通过后执行函数调用
// fn1 先,fn2 后
function fn1() {
console.log('fn1');
return new Promise((reslove, reject) => {
setTimeout(() => {
reslove('fn2')
}, 1000);
})
}
async function fn2() {
console.log('fn2上');
const param = await fn1()
console.log(param);
console.log('fn2下');
}
fn2()