一、Promise
Promise是ES6中的一个新增的对象,通过他可以实现同步代码实行异步操作,防止代码层层嵌套的回调地狱的问题
- 1.Promise 有三个状态:pengding,fulfilled,rejected,三个状态是不可逆的
- 2.Promise对象并不是异步的,只要创建Promise对象就会立即调用promise里面的代码
- 3.promise 是如何实现异步操作的?
通过状态来实现的,promise里面有三个状态——pending(默认,没有告诉程序状态时成功还是失败)fulfilled和rejected,不同的状态会触发不同的函数 - 4.可以通过函数来监听状态的变化
resolve-->then(); reject-->catch();
- 5.创建promise对象的基本格式:
let promise=new Promise(function(resolve,reject){ console.log("promise");//pending状态 resolve();//将状态从pending改为fulfilled,执行then方法 rejecte();//将状态从pending改为rejected执行绑定的catch方法 } promise.then(function(){}); promise.catch(function(){}); example: let promise=new Promise(function (resolve,reject){ console.log(111); // reject(); resolve(); }); promise.then(function (){ console.log(222); }); promise.catch(function (){ console.log(333); });
二、Promise.then方法
1 then函数可以接收两个函数作为参数,分别对应promise对象成功和失败状态执行的方法
promise.then(function (){ console.log("success"); },function (){ console.log("failure"); });
2 通过reject和resolve可以传递参数给then方法中的对应状态的函数
let p=promise.then( function (data){ console.log("success",data); return "aaa"; },function (data){ console.log("failure",data); return "bbb"; });
3 同一个promise函数可以执行多个then函数,多次调用then方法,所有定义的then方法都会被执行
4 promise返回的对象是一个新的promise对象
console.log(p); console.log(p === promise);//false
5 promise对象的then方法可以给下一个promise对象的then方法传递参数
// 注意点:不管是在上一个promise对象回调成功的函数还是失败的函数传递参数,都会把参数传递给下一个promise对象成功的回调
promise.then(function (data){ console.log("success",data); return p2; },function (data){ console.log("failure",data); return p2; })
6 promise对象可以给下一个promise对象传递一个promise对象,该promise对象的状态决定下一个then方法执行的是成功的回调还是失败的回调,同时能够给下一个then方法传递参数
let p2=new Promise(function (resolve,reject){ console.log(444); resolve("shanjialan"); }); p.then(function (data){ console.log("success",data); },function (data){ console.log("failure",data); })
Promise-catch方法
- catch其实就是promise-then方法的一个语法糖,
catch 其实就是then(undefined,()=>)的语法糖 - promise如果是默认状态(pending)或者成功(fulfilled),没有监听也不会报错,但是失败(rejected)没有监听则会报错
let promise=new Promise(function (resolve,reject){ // resolve("s1"); --浏览器没有任何输出 reject("s1");//报错 })
正是由于这个原因,promise一般采用链式编程,相当于之前的new Promise(function(){},function(){});
new Promise(function(){ //code }, function(){ //code }); //等价于 promise.then(function(){}).catch(function(){ //code })
注意:只能链式编程,不能分开监听,否则报错
为什么采用链式编程?
promise如果是默认状态(pending)或者成功(fulfilled),没有监听也不会报错,但是失败(rejected)没有监听则会报错,promise-then会返回一个新的promise,而且返回的promise的状态继承上一个promise的状态,如果上一个promise的状态是rejected,则新的promise的状态也为rejected,因此第二个promise也必须要进行失败的监听
let promise2=new Promise(function (resolve,reject){ // resolve("s1"); --浏览器没有任何输出 reject("f2"); }) promise2.then(function (data){ console.log(data); }, function (data){ console.log(data); }); let p3= promise2.catch(function (data){ console.log(data); }); //error:Uncaught (in promise) f2) // 因此在开发过程中使用promise进行监听采用链式编程 // 解决错误方案: p3.catch(function (){ console.log("catch error missing"); });
怎样解决非链式编程的报错?
给下一个promise的对象添加catch回调函数即可
// 解决错误方案: p3.catch(function (){ console.log("catch error missing"); });
二、catch方法的特点
- 和then方法一样,可以给下一个promise对象传递参数
- 同一个promise对象可以调用多个catch,当该对象的状态为rejected时,所有的catch方法都会被调用
- catch方法返回一个新的promise对象
- 可以让上一个promise传递一个参数给下一个promise对象,但是不管下一个
- promise对象是成功的状态还是失败的对象,接收到的参数都是上一个promise-catch传递的参数
- catch函数可以返回一个promise对象,返回的promise与catch方法调用的promise对象的状态一样
- catch方法可以捕获上一个promise对象then方法的一个异常
let promise3=new Promise(function (resolve,reject){ // reject("failure3"); resolve("succeeded3!") }) promise3.then(function (){ console.log("success"); xxx; }).catch(function(e){ console.log("failure",e); }) //成功捕获上一个promise的成功回调的错误,报错信息:failure ReferenceError: xxx is not defined at 4-promise-catch.html?_ijt=frlqsu3mnkee7rs8dlqav223j7:63
代码中的XXX是未定义的东西,通过链式编程的catch可以获取上一个promise对象resolve回调函数中的异常并输出显示,这个是catch回调函数和then函数不大一样的一个特点。