- Promise的构造函数是同步执行,Promise.then中的函数是异步执行。
**
const promise = new Promise((resolve, reject)=>{
console.log(1);
resolve();
console.log(2);
});
promise.then(()=>{
console.log(4);
});
console.log(5);
- 构造函数中的 resolve 或 reject 只有第一次执行有效,多次调用没有任何作用。promise 状态一旦改变则不能再变。 promise 有 3 种状 态: pending、fulfilled 或 rejected。 状态改变只能是 pending->fulfilled 或者 pending-> rejected,状态一旦改变则不能再变。 ```javascript
const promise = new Promise((resolve, reject) => { resolve(‘success1’) reject(‘error’) resolve(‘success2’) });
promise .then((res) => { console.log(‘then: ‘, res) }) .catch((err) => { console.log(‘catch: ‘, err) })
![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607679818698-47eafb72-558f-48a9-9ade-0daf3632dab6.png#align=left&display=inline&height=514&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1028&originWidth=1786&size=151046&status=done&style=none&width=893)<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607679870700-5417b21f-8b39-4297-8569-b520f05b41ff.png#align=left&display=inline&height=497&margin=%5Bobject%20Object%5D&name=image.png&originHeight=994&originWidth=1858&size=149610&status=done&style=none&width=929)
3. **promise 的 .then 或者 .catch 可以被调用多次,但这里 Promise 构造函数只执行一次。或者说 promise 内部状态一经改变,并且有了一个值,那么后续每次调用 .then 或者 .catch 都会直接拿到该值。**
**
```javascript
const promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log('once')
resolve('success')
}, 1000)
})
const start = Date.now()
promise.then((res) => {
console.log(res, Date.now() - start)
})
promise.then((res) => {
console.log(res, Date.now() - start)
})
console.log('start');
new Promise(function (resolve, reject) {
setTimeout(function () { //定时器模拟异步
resolve('hello'); //修改promise状态调用then中的第一个函数
}, 2000);
}).then((value) => {
console.log(value); //接收resolve传来的值
return new Promise(function (resolve) { //该then()返回一个新的promise实例,后面可以继续接then
setTimeout(function () {
resolve('world'); //修改新promise的状态,去调用then
}, 3000)
})
}).then((value) => {
console.log(value);
})
输出结果: 立即输出 start 两秒输出 hello 再三秒 world
- 上面我们在 then() 函数中返回的是一个新的promise,如果返回的不是一个新的promise会怎样呢?依然是上面的代码,稍作修改。 ```javascript
console.log(‘start’); new Promise(function (resolve, reject) { setTimeout(function () { resolve(‘hello’); }, 2000); }).then((value) => { console.log(value); (function () { return new Promise(function (resolve) { setTimeout(function () { resolve(‘world’); }, 3000) }) })(); return false; }).then((value) => { console.log(value); })
结果: 立即输出 start 两秒输出 hello 三秒输出 false<br />![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607680579088-8d2c6ed9-57c4-4986-81ee-d4b0ba225f38.png#align=left&display=inline&height=635&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1270&originWidth=1816&size=204925&status=done&style=none&width=908)<br />**根据上面的运行结果来看,如果在一个then()中没有返回一个新的promise,则return 什么下一个then就接受什么,在上面的实例代码中return的是false,下一个 then中接受到的value就是false,如果then中没有return,则默认return的是 undefined.**
6. **then()中包含.then()的嵌套情况 then()的嵌套会先将内部的then()执行完毕再继续执行外部的then();在多个then嵌套时建议将其展开,将then()放在同一级,这样代码更清晰。**
```javascript
console.log('start');
new Promise((resolve, reject) => {
setTimeout(function () {
console.log('step');
resolve(110);
}, 1000)
})
.then((value) => {
return new Promise((resolve, reject) => {
setTimeout(function () {
console.log('step1');
resolve(value);
}, 1000)
})
.then((value) => {
console.log('step 1-1');
return value;
})
.then((value) => {
console.log('step 1-2');
return value;
})
})
.then((value) => {
console.log(value);
console.log('step 2');
})
/* start step step1 step 1-1 step 1-2 110 step 2 */
//展开之后的代码
console.log('start');
new Promise((resolve, reject) => {
setTimeout(function () {
console.log('step');
resolve(110);
}, 1000)
})
.then((value) => {
return new Promise((resolve, reject) => {
setTimeout(function () {
console.log('step1');
resolve(value);
}, 1000)
})
})
.then((value) => {
console.log('step 1-1');
return value;
})
.then((value) => {
console.log('step 1-2');
return value;
})
.then((value) => {
console.log(value);
console.log('step 2');
})
- catch和then的连用 如果每一步都有可能出现错误,那么就可能出现catch后面接上then的情况。 ```javascript new Promise((resolve, reject) => { resolve(); }) .then(value => { console.log(‘done 1’); throw new Error(‘done 1 error’); }) .catch(err => { console.log(‘错误信息1:’ + err); }) .then(value => { console.log(‘done 2’); }) .catch(err => { console.log(‘错误信息2:’ + err); }) // done 1 错误信息1:Error: done 1 error done 2 说明catch后面会继续执行then,catch返回的也是一个promise实例 ß new Promise((resolve, reject) => { resolve(); }) .then(value => { console.log(‘done 1’); throw new Error(‘done 1 error’); }) .catch(err => { console.log(‘错误信息1:’ + err); throw new Error(‘catch error’); }) .then(value => { console.log(‘done 2’); }) .catch(err => { console.log(‘错误信息2:’ + err); }) // done 1 错误信息1:Error: done 1 error 错误信息2:Error: catch error 如果在catch中也抛出了错误,则后面的then的第一个函数不会执行,因为返回的 promise状态已经为rejected了
![image.png](https://cdn.nlark.com/yuque/0/2020/png/154143/1607681109057-98a08a44-38be-4f51-97a3-5eec23b25a0a.png#align=left&display=inline&height=239&margin=%5Bobject%20Object%5D&name=image.png&originHeight=478&originWidth=1862&size=82507&status=done&style=none&width=931)
8. **Promise.all() 将多个Promise批量执行,所有的Promise都完毕之后返回一个新的Promise**
```javascript
// 1、接收一个数组作为参数
// 2、数组中可以是Promise实例,也可以是别的值,只有Promise会等待状态的改变
// 3、所有子Promise完成,则该Promise完成,并且返回值是参数数组中所有Promise实例的结果组成的数组
// 4、有任何一个Promise失败,则该Promise失败,返回值是第一个失败的Promise的结果
console.log('here we go');
Promise.all([1, 2, 3])
.then(all => {
console.log('1: ' + all);
return Promise.all([function () {
console.log('ooxx');
}, 'xxoo', false])
})
.then(all => {
console.log('2: ' + all);
let p1 = new Promise(resolve => {
setTimeout(function () {
resolve('I\'m p1');
}, 1500)
});
let p2 = new Promise(resolve => {
setTimeout(function () {
resolve('I\'m p2');
}, 2000)
});
return Promise.all([p1, p2]);
})
.then(all => {
console.log('3: ' + all);
let p1 = new Promise((resolve, reject) => {
setTimeout(function () {
resolve('P1');
}, 1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(function () {
reject('P2');
}, 3000)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(function () {
reject('P3');
}, 2000)
})
return Promise.all([p1, p2, p3]);
})
.then(all => {
console.log('all: ' + all);
})
.catch(err => {
console.log('Catch:' + err);
})
// here we go 1: 1,2,3 2: function(){ console.log('ooxx'); },xxoo,false 3: I'm p1,I'm p2 Catch:P3 证明了上面的四点。
- Promise.race() 和Promise.all()差不多,区别就是传入的数组中有一个Promise完成了则整个Promise完成了。
let p1 = new Promise(resolve => {
setTimeout(function () {
resolve('p1');
}, 10000);
})
let p2 = new Promise(resolve => {
setTimeout(function () {
resolve('p2');
}, 1000);
})
Promise.race([p1, p2])
.then((value) => {
console.log(value);
})
// p1 1s之后输出 。。 等待十秒后代码才算执行完毕