学习promise
总概括
- promise是js异步编程的一种解决方案
- 我对promise的认识(通俗):给一个承诺promise,如果未来发生的事情(异步操作)是符合满足相应条件,则接受resolve,否则失败reject。这个决定是一旦做了,就不会发生改变。根据接受或失败承诺来决定下一步then应该做什么
- promise的基本使用
- 调用new Promise(func)构造函数,func是一个函数,会立即执行(和一般回调用不同)
- 一个promise的决议是一次且不可更改的
- 一个promise只有三种状态:pending, rejected, fulfilled
- resolve, reject不会终结函数的执行,只是设置了一下状态
- promise.then是promise决议后的下一步操作,它的返回仍是一个Promise对象
1 //通过构造函数创建一个Promise对象
2 //构造函数的参数是一个函数,该函数参数为resovle和reject
3 //异步操作成功时调用resolve,失败时调用reject
4 var promise = new Promise(function(resolve, reject){
5 if(/*异步成功*/){
6 resolve(value);//调用resolve,将promise状态置为接受
7 }
8 else{
9 reject(error);//调用reject,将promise状态置为拒绝
10 }
11 });
12 //根据上面promise决议的结果,then决定下一步怎么做
13 promise
14 .then(
15 function(){/*promise决议结果为resolved*/},
16 function(){/*promise决议结果为rejected*/}
17 )
- Promise.prototype.then()决议后下一步的回调
- Promise.prototype.catch()决议中出现异常错误时的回调
- Promise.all([p1,p2...])参数为多个promise构成的数组,一个rejected则全部rejected,所有fulfilled才fulfilled
- Promise.race([p1,p2...])参数为多个promise构成的可枚举对象(如数组),以最先完成的为准
- Promise.resolve(), Promise.reject():直接返回决议fulfilled或rejected的promise
Promise的决议
- promise只有三种状态:pending(未决议),fulfilled(成功),rejected(失败)
- 只决议一次,无法修改,无法中途取消或修改
1 var promise = new Promise(function(resolve, reject){
2 setTimeout(function(){
3 resolve('resolve');
4 reject('reject');//这次的决议会被忽略
5 }, 3000);
6 })
7 promise.then(
8 function(){
9 console.log('第一次resolve');//setTimeout后,决议结果为resolve。虽然promise在下面会指向另一个rejected的对象
10 },
11 function(){
12 console.log('第一次reject');
13 }
14 )
15 //把promise指向另一个对象(决议失败)
16 promise = new Promise(function(resolve, reject){
17 reject();
18 })
19 promise.then(
20 function(){
21 conosle.log('第二次resolve');
22 },
23 function(){
24 console.log('第二次reject');
25 }
26 )
Promise.prototype.then()
- promise状态改变时的回调函数,接受两个参数,第一个是fulfilled回调,第二个是rejected回调
- 如果promise状态是pending的话,then里面的操作是不会执行的
- 仍然返回一个Promise对象,不是原来那个!
- 基于第二点,可以链式执行then。promise.then().then()...
- 对一个promise决议结果注册多个then,执行时按注册顺序执行(链式也是先执行完第一次注册的)
1 var promise = new Promise((resolve, reject)=>{
2 resolve('resolve');
3 })
4 var p1 = promise.then(()=>{
5 console.log('第一个resolve then');
6 })
7 .then(function(){
8 console.log('第一个resolve then后继续执行then')
9 })
10 var p2 = promise.then(()=>{
11 console.log('第二个resolve then');
12 })
13 .then(()=>{
14 console.log('第二个resolve then后继续执行then');
15 })
16 //执行结果
17 //第一个resolve then
18 //第二个resolve then
19 //第一个resolve then后继续执行then
20 //第二个resolve then后继续执行then
Promise.prototype.catch()
- 用于指定发生错误时的回调函数,是.then(null, function(err){})的别名,也是返回一个promise(fulfilled)
- 在运行中抛出错误,状态会变成rejected。先注册了reject,则执行reject,若reject中无错则不再执行catch。否则执行catch
- 先resolve(状态已经确定),之后抛出错误,不会被catch捕获
- Promise 会吃掉错误:在promise内部的错误不会被外部发现
1 //catch会捕获错误
2 var promise = new Promise((resolve, reject)=>{
3 throw new Error('promise error');
4 });
5 // promise.then(null, ()=>{
6 // console.log('故意throw Error,注册的reject回调');
7 // })
8 promise
9 .catch((err)=>{
10 console.log('故意throw Error catch error: ', err);
11 console.log(promise);
12 })
13 //Promise会吃掉错误
14 promise = new Promise((resolve, reject)=>{
15 resolve();
16 throw new Error('promise error');//这个错误不会在外部被发现
17 console.log('抛出错误后的部分');//这里也不会执行
18 });
19 promise.then(()=>{//虽然throw错误了,但还是会执行这个resolve回调
20 console.log('resolve后,throw Error,注册的resolve回调');
21 })
22 .catch((err)=>{//并不能捕获上面resolve后的错误
23 console.log('resolve后,throw Error,注册的catch回调: ', err);
24 })
Promise.all([p1, p2, p3])
- 当参数中所有promise都是fulfilled,才返回fulfilled promise
- 当出现一个rejected,则直接返回rejected promise。即使其它还在pending
- 参数中promise间不互相影响。如果前一个异常,后面也不会停止
1 function tickPromise(index, t){ 2 return new Promise((resolve, reject)=>{ 3 setTimeout(function(){ 4 resolve(); 5 console.log('Promise.all 这是第' + index + '个promise'); 6 }, t); 7 }) 8 } 9 Promise.all([Promise.reject('reject'), tickPromise(1, 1000)]) 10 .then( 11 function(){ 12 console.log('Promise.all reject先执行完:resolve'); 13 }, 14 function(){ 15 console.log('Promise.all reject先执行完:reject'); 16 } 17 )
Promise.race([p1, p2, p3])
以最先执行的promise为准
Promise.resolve()
参数 | 操作 |
Promise对象 | 直接返回该对象(状态一致) |
有then函数的对象 | 先返回pending状态promise,接着立即调用then函数 |
普通对象或值 | 以该值为参数调用resolve,返回一个promise |
1 var promise = Promise.resolve({ 2 then: function(resolve, reject){ 3 console.log('Promise.resolve: thenable对象的then函数'); 4 setTimeout(function(){resolve()}, 3000); 5 } 6 }); 7 console.log('promise.resolve刚赋值后的promise: ', promise); 8 var interval = setInterval(function(){console.log(promise)}, 1000); 9 setTimeout(function(){clearInterval(interval)}, 4000); 10 //结果: 11 //promise.resolve刚赋值后的promise: Promise {<pending>} 12 //Promise.resolve: thenable对象的then函数 13 //Promise {<pending>} 14 //Promise {<pending>} 15 //Promise {<pending>} 16 //Promise {<resolved>: undefined}
Promise.reject(param)
返回一个Promise,状态为rejected,值为传入的参数param