回调地狱:需要控制异步函数的执行顺序,而将他们层层嵌套,使得代码结构复杂,难以维护。
Promise 缓解了回调地狱
没有彻底解决回调地狱。
then的处理函数依然是callback
Promise 的意义在于 统一 异步实现的方案(callback变得可控)
callback 实现异步,不同开发者,三方库的设计都不统一(注入参数,callback位置,数量等)。
配合 async await 彻底解决回调地狱
同样的道理,可以对Promise实例进行封装
function async500() {
return new Promise(function(resolve) {
setTimeout(() => {
console.log("async500公共的操作")
resolve("要等500ms传递数据");
}, 500)
})
}
function async1000() {
return new Promise(function(resolve) {
setTimeout(() => {
console.log("async1000公共的操作")
resolve("要等100ms传递数据");
}, 1000)
})
}
// 执行
async500().then((data) => {
// 500ms后执行操作
console.log(data);
return async1000();
}
).then((data) => {
// 1000ms后执行操作
console.log(data);
return async1000() // return async500();
}).then(···
Promise 将原本异步嵌套的结构转变成成流式的书写,很好的解决了回调地狱的问题。
async function 异步函数
使用Promise仍然较为复杂,为了更简便的编写代码。
function print(delay, message) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
print(1000, "First").then(function () {
return print(4000, "Second");
}).then(function () {
print(3000, "Third");
});
async function asyncFunc() {
await print(1000, "First");
await print(4000, "Second");
await print(3000, "Third");
// await 会返回 resolve 的数据, 因而可以通过变量来接受
// let data = await xxx(); //xxx()指返回Promise的函数
}
asyncFunc();
await 指令后必须跟着一个 Promise,异步函数会在这个 Promise 运行中暂停,直到其运行结束再继续运行。
异步函数实际上原理与 Promise 原生 API 的机制是一模一样的,只不过更便于程序员阅读。
如果 Promise 有一个正常的返回值,await 语句也会返回它
async 函数一定会返回一个 promise 对象。
Promise.resolve(···) 调用时直接resolve
Tips: 可以对回调函数使用async~
let a = async fun() a.[Symbol.toStringTag] === 'AsyncFunction' // true Object.prototype.toString.call(a) === '[object AsyncFunction]' // 引申,自定义对象设置 Symbol.toStringTag 可以改变 toString 行为