promise

原文地址

要实现Promise对象首先我们要了解Promise拥有哪些特性,简单概括为以下几点
1、Promise有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)
2、Promise对象接受一个回调函数作为参数, 该回调函数接受两个参数,分别是成功时的回调resolve和失败时的回调reject;另外resolve的参数除了正常值以外, 还可能是一个Promise对象的实例;reject的参数通常是一个Error对象的实例。
3、then方法返回一个新的Promise实例,并接收两个参数onResolved(fulfilled状态的回调);
onRejected(rejected状态的回调,该参数可选)
4、catch方法返回一个新的Promise实例
5、finally方法不管Promise状态如何都会执行,该方法的回调函数不接受任何参数
6、Promise.all()方法将多个多个Promise实例,包装成一个新的Promise实例,该方法接受一个由Promise对象
组成的数组作为参数(Promise.all()方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例),注意参数中只要有一个实例触发catch方法,都会触发Promise.all()方法返回的新的实例的catch方法,如果参数中的某个实例本身调用了catch方法,将不会触发Promise.all()方法返回的新实例的catch方法
7、Promise.race()方法的参数与Promise.all方法一样,参数中的实例只要有一个率先改变状态就会将该实例的状态传给Promise.race()方法,并将返回值作为Promise.race()方法产生的Promise实例的返回值
8、Promise.resolve()将现有对象转为Promise对象,如果该方法的参数为一个Promise对象,Promise.resolve()将不做任何处理;如果参数thenable对象(即具有then方法),Promise.resolve()将该对象转为Promise对象并立即执行then方法;如果参数是一个原始值,或者是一个不具有then方法的对象,则Promise.resolve方法返回一个新的Promise对象,状态为fulfilled,其参数将会作为then方法中onResolved回调函数的参数,如果Promise.resolve方法不带参数,会直接返回一个fulfilled状态的 Promise 对象。需要注意的是,立即resolve()的 Promise 对象,是在本轮“事件循环”(event loop)的结束时执行,而不是在下一轮“事件循环”的开始时。

  • 主要是用来解决异步编程回调地狱的问题

回调地狱

1
2
3
4
5
6
7
8
9
10
11
12
<script>
var dom = document.getElementById('#div1');
setTimeout(() => {
dom.style.width = '100px';
setTimeout(() => {
dom.style.height = '100px';
setTimeout(() => {
dom.style.color = 'red';
}, 1000)
}, 1000)
}, 1000)
</script>

Promise基本使用

  • Promise就像是一个先知,并且它预先设置了成功失败要执行的回调函数
    • 成功失败代表Promise的两种状态
    • 成功:比如如果后台返回的响应状态码为200并且返回了正确的数据,Promise就把状态改成成功,并且执行成功的回调函数
    • 失败:比如如果响应状态码500,Promise就把状态改成失败,并且执行失败的回调函数
  1. 通过new实例化Promise
  • 参数是一个函数
  1. 通过then设置成功和失败的回调函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
new Promise((resolve, reject) => {
resolve(1)
// reject(2)
}).then((data) => {
console.log('成功',data)
}, (data) => {
console.log('失败',data)
})


// resolve和reject分别用来执行`成功`和`失败`的回调函数
Promise的三种状态
pending 初始状态
fulfilled 成功
rejected 失败

// 状态一旦发生改变,就不再改变
// 要不执行resolve(),要不执行reject()

.then 成功的回调 // then可以链式调用
.catch 失败的回调
.finally 无论成功失败的回调

Promise.resolve // 返回一个Promise,并且自动执行resolve方法
Promise.reject // 返回一个Promise,并且自动执行reject方法

Promise.all
// 所有子实例的状态都变为fulfilled时,父实例的状态才会变成fulfilled,子实例的返回值组成一个数组传到父实例的回调函数。
// 如果任何一个子实例的状态变为rejected,父实例的状态就变为rejected,并把第一个rejected实例的返回值传给父实例的回调函数。

Promise.race // 接收第一个改变状态的子实例的状态和返回值

async/await

  • promise generator语法糖

  • async作为一个关键字放到函数前面

    任何一个 async 函数都会隐式返回一个 promise

  • await 关键字只能在使用 async 定义的函数中使用

    await后面可以直接跟一个 Promise实例对象

    await函数不能单独使用

  • async/await 让异步代码看起来、表现起来更像同步代码

1
2
3
4
5
6
7
8
9
10
11
12
async function queryData() {
var ret = await new Promise((resolve) => {
setTimeout(function(){
resolve('nihao')
},1000);
})
return ret;
}
queryData().then(function(data){
console.log(data)
})

async处理多个异步函数

1
2
3
4
5
6
7
8
9
10
11
12
13
async function queryData() {
// 添加await之后 当前的await 返回结果之后才会执行后面的代码
var info = await new Promise((resolve) => {
setTimeout(() => {
resolve('info')
}, 1000)
});
var ret = await Promise.resolve({data: info + '123'});
return ret.data;
}
queryData().then(function(data){
console.log(data)
})