多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
即使不是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 ```