回调函数
在javascript初期,我们通常使用回调函数来处理异步请求,下面是一个例子。
function fn(callback) {
const param = 'value';
setTimeout(() => {
callback(param);
}, 1000);
}
fn((param) => {
console.log(param);
});
例子中通过回调函数的方式实现了延时1s的异步处理。一切看起来很美好,但现实很残酷,再来看一个例子。
function fn1(callback) {
const param = 'value1';
setTimeout(() => {
callback(param);
}, 1000);
}
function fn2(callback) {
const param = 'value2';
setTimeout(() => {
callback(param);
}, 2000);
}
function fn3(callback) {
const param = 'value3';
setTimeout(() => {
callback(param);
}, 3000);
}
fn1((param1) => {
console.log(param1);
fn2((param2) => {
console.log(param2);
fn3((param3) => {
console.log(param3);
});
});
});
例子中实现了分别延时1s、2s、3s输出相应结果。
当我们需要调用多个异步请求时,就会出现这种回调嵌套多层的情况。上述实例虽然能够实现功能,但非常不易阅读,这种现象叫做“回调地狱”,我们应当极力避免。Promise
随着技术的发展,Promise在es6标准中被提出。下面是通过promise进行延时1s的异步处理。
function fn() {
let param = 'value';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 1000);
});
}
fn().then((param) => {
console.log(param);
});
处理多个任务,看起来也清爽了很多。
function fn1() {
let param = 'value1';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 1000);
});
}
function fn2() {
let param = 'value2';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 2000);
});
}
function fn3() {
let param = 'value3';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 3000);
});
}
fn1().then((param) => {
console.log(param);
return fn2();
}).then((param) => {
console.log(param);
return fn3();
}).then((param) => {
console.log(param);
});
Promise已经把多个异步任务分割开,不过代码还是相对复杂。async/await
ES7中提出的async函数,让异步处理有了终极方案。
定义一个async函数,通过await等待异步任务完成。
function fn() {
const param = 'value';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 1000);
});
}
async function fn1() {
const param = await fn();
console.log(param);
console.log('异步函数已执行完成');
}
fn1();
再看一下处理多个任务的实例。
function fn1() {
const param = 'value1';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 1000);
});
}
function fn2() {
const param = 'value2';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 2000);
});
}
function fn3() {
const param = 'value3';
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(param);
}, 3000);
});
}
async function resFn() {
const param1 = await fn1();
console.log(param1);
const param2 = await fn2();
console.log(param2);
const param3 = await fn3();
console.log(param3);
}
resFn();
与同步代码没什么区别,so cool~