回调地狱
如果,我们现在有多个异步函数,而我们又希望这些 土鸡瓦狗 都能按照我们的想法来执行代码,有了上一次回调函数的打怪经验,我们来看一下如下代码:
setTimeout(() => {
console.log('1')
setTimeout(() => {
console.log('2')
setTimeout(() => {
console.log('3')
setTimeout(() => {
console.log('4')
setTimeout(() => {
console.log('5')
setTimeout(() => {
console.log('6')
}, 0)
}, 0)
}, 0)
}, 0)
}, 0)
}, 0)
//依次打印:1 2 3 4 5 6
看一下,这种回调函数的层层嵌套,就叫做回调地狱。回调地狱会造成代码可复用性不强,可阅读性差,可维护性(迭代性差),扩展性差等等问题。
问:能解决问题吗?
答:可以!但是不推荐。
Promise来了
Promise最早是社区提出来解决回调地狱的,而后被Es6收录。
是什么?
Promise,意为“承诺”,只要你敢用我,我就承诺给你返回一个实例对象。
Promise本质上是一个构造函数,用来生成Promise实例;
const promise = new Promise(function(resolve, reject) {});
Promise构造函数,可以接受一个函数作为参数,这个函数的两个参数分别是resolve
和reject
- resolve 函数的作用是将Promise对象的状态从未完成变为成功
- reject 函数的作用是将Promise对象的状态从未完成变为失败
Promise对象有三种状态:pending、fulfilled 和 rejected,分别对应:进行中、成功和失败;
- 一旦状态从pending变为成功或者失败,就无法改变这个状态。
- 对象的状态不受外界影响,只有异步操作的结果,可以决定当前是哪一种状态
Promise构建出来的实例有以下方法:
- .then()
- .catch()
- finally()
then()
then是实例状态发生改变是的回调函数,它的第一个参数是resolved状态下的回调函数,第二个参数是rejected状态下的回调函数。且then方法返回的是一个新的Promise实例,这也是Promise可以链式调用的原因
catch()
一般来说,使用catch方法代替then()第二个参数,就是rejection状态下的用于指定发生错误时的回调函数
finally()
finally()方法用于指定不管 Promise 对象最后状态如何,都会执行的操作