即使不是reject的错误,在错误函数中一样能够获得
```
var p = new Promise((resolve, reject) => {foo.bar(); resolve(1);})
p.then(data => console.log(data), err => console.log('ooh...', err)); //ohh... foo is not defined
```
如果是resolve函数中的错误,那么错误就无法走到reject函数中
```
var p = new Promise((resolve, reject) => resolve(1));
p.then(data => foo.bar(), err => console.log(err)); //直接抛错
```
```
var p = new Promise((resolve, reject) => resolve(1));
p.then(data => foo.bar(), err => console.log(err))
.catch(err => console.log('ooh...', err)); //ooh.. foo is not defined
```
如果resolve一个promise,那么两个promise会进行异步展开并返回一个promise(如果完成或拒绝函数返回一个Promise,它将会被展开,不管它的决议是什么,都会成为当前then返回的链接Promise的决议值)
```
var p1 = new Promise((resolve, reject) => resolve(42));
var p2 = new Promise((resolve, reject) => resolve(p1));
var p3 = new Promise((resolve, reject) => resolve(p2));
p3.then(data => console.log(data)); //42
```
下面两个的行为是一样的,我们更喜欢用第一种
```
var p1 = new Promise((resolve, reject) => resolve(42));
var p2 = Promise.resolve(42);
```
而如果向Promise.resolve传递一个真正的promise,则只会返回一个promise
```
var p1 = Promise.resolve(42);
var p2 = Promise.resolve(p1);
p1 === p2; //true
```
#### 链式流
每次调用.then都会返回一个新的Promise,不管回调函数返回的值是什么,该值都会被包成新的promise供下一个链式使用(没有返回值则是undefined)
```
var p = Promise.resolve(21);
p.then(v1 => {console.log(v1); return v1 * 2})
.then(v2 => console.log(v2))
.then(v3 => console.log(v3));
// 21
// 42
//undefined
```
直接return并不直观,因此建议用:
```
var p = new Promise.resolve(21);
p.then(v1 => {console.log(v1); return new Promise(resolve => resolve(v1 * 2))})
.then(v2 => console.log(v2))
.then(v3 => console.log(v3));
```
这就是promise的强大之处,每一步都必须等待前一步结束:
```
var p = Promise.resolve(21);
p.then(v => {console.log(v); return new Promise(resolve => setTimeout(() => resolve(v * 2), 100))})
.then(nv => console.log(nv));
//21
//100ms后 42
```
.then的完成函数或拒绝函数中发生的异常都会在下一个then的异常函数中捕获
出现异常,在拒绝函数中处理后promise会继续执行下去。如果谁都没有处理这个异常,那么就会走到catch中并且中断整个Promise
前面提到的,resolve中传入一个Promise则会对两个Promise进行展开,如果reject中传入一个Promise则不会展开,.then的拒绝函数中接收的是这个reject的传入的Promise
```
var p = Promise.reject('oops');
var p1 = new Promise((resolve, reject) => resolve(p));
p1.then(v => console.log(v), err => console.log('ooh...', err)); //ooh... oops
var p = Promise.resolve(21);
var p1 = new Promise((resolve, reject) => reject(p));
p1.then(v => console.log('not error'), err => console.log(err)); //Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: undefined}
```
#### 错误处理
try catch只能处理同步错误
```
try {
setTimeout(() => baz.bar(), 100);
//100ms后抛出全局错误
}
catch(err) {console.log('oops'); /*永远不会走到catch中*/
}
```
#### API
all
只有所有的promise都完成了all才会完成,有一个出错整体就reject
记住要为每一个promise做错误处理而不仅仅是给all
```
var p1 = Promise.resolve(21);
var p2 = Promise.resolve(22);
Promise.all([p1, p2]).then(data => console.log(data)); //[21, 22]数组
```
race
同样接收promise数组返回promise,但是promise们是处于竞争状态的,有一个先resolve则整体就resolve了,整体resolve的值就是该promise resolve的值(先到的先胜利)。有任何一个reject了则整体reject。
promise无论是.then还是.catch都是返回promise
```
function foo(x ,y) {
return new Promise(resolve => resolve(x + y)).then(v => v * 2);
}
foo(2, 3).then(v => console.log(v)); //10
//因为new Promise(...).then(...)返回这个Promise,所以foo(2, 3)可以继续使用这个promise,由于return v * 2会包装成Promise传入到下一个then中,所以最后的v是10
```
- 你不知道的JS上
- 第一部分 第三章 函数作用域和块作用域
- 第一部分 第四章 提升
- 第一部分 第五章 闭包
- 第二部分 第一章 关于this
- 第二部分 第二章 this全面解析
- 第二部分 第三章 对象
- 第二部分 第五章 原型
- 第二部分 第六章 行为委托
- 你不知道的JS中
- 第一部分 第二章 值
- 第一部分 第三章 原生函数
- 第一部分 第四章 强制类型转换
- 第一部分 第五章 语法
- 第二部分 第一章 异步
- 第二部分 第三章 Promise
- 第二部分 第四章 生成器
- 第二部分 第五章 性能
- 你不知道的JS下
- 第一部分 总结
- 第二部分 第二章 语法
- 第二部分 第三章 代码组织
- 第二部分 第四章 Promise
- 第二部分 第五章 集合
- 第二部分 第六章 新增API
- 第二部分 第七章 元编程
- 第二部分 第八章 ES6之后