Promise是一种异步编程的解决方案,比传统的解决方案(回调函数和事件)更加合理和强大。它首先由社区发布和实施。ES6将其写入语言标准,统一使用,原生提供Promise对象。所谓Promise,简单来说就是一个容器,里面装的是将来会结束的事件(通常是异步操作)的结果。从语法上讲,Promise是一个对象,可以从中获取异步操作的消息。Promise提供了统一的API,各种异步操作可以统一处理。有了Promise对象,异步操作就可以表达在同步操作的过程中,避免了层层嵌套的回调函数。此外,Promise对象提供了统一的接口,更容易控制异步操作??。异步解决方案:1)传统的ajax是一种异步的JavaScript请求,可以在不影响当前进程的情况下与后台进行交互。延时2.监听(成功,失败)通过判断状态码确定执行哪个回调函数200ok404未找到500后台代码异常403访问不到304文档内容未改变3.调用回调函数完成处理后请求$.getJSON('http://120.78.164.247:8080/grade',function(data){alert(data)});警报('结束');//先执行end弹出数据问题:在回调函数中如果中间嵌套很多,容易出错2)promisepromise中的三种状态:1.未知状态,2.成功状态,resolve()Unknownstate---》Successstate3.Failurestate,reject()Unknownstate---》失败状态ajax用的最多letpromise=newPromise((resolve,reject)=>{$.ajaxSetup({error:function(){reject()};//失败});$.get('',function(data){resolve(data);//成功});promise.then(()={}.catch(()=>{});在我的理解中promise是对ajax的一种封装,在上面的代码中,将jQuery封装的ajax代码分为两部分。异步操作Ajax的封装1、我们看一下自己封装一个Ajaxletfetch=(method,url,successHandler,errorHandler)=>{letxhr=newXMLHttpRequest();xhr.open(方法,网址);xhr.responseType='json';xhr.setRequestHeader('Accept','application/json');//设置header信息xhr.onreadystatechange=function(){if(this.readyState==4){if(this.status==200){successHandler(this.response)}else{errorHandler(this.response);};}};xhr.发送();不能在node中使用,2.看一下用promise封装简单的思路:letpromise=newPromise((resolve,reject)=>{setTimeout(function(){//模拟异步请求if(Math.round(Math.random()*10)>5){resolve('success');//success}else{reject('erro');//failure}},3000);});承诺.then((data)=>{console.log(data);}).catch((erro)=>{console.log(erro);});看看promise是如何封装ajax的letfetch=(method,url)=>{returnnewPromise((resolve,reject)=>{letxhr=newXMLHttpRequest();//声明一个请求xhr.open(method,url);xhr.responseType='json';xhr.setRequestHeader('Accept','application/json');xhr.onreadystatechange=function(){if(this.readyState==4){//判断状态if(this.status==200){resolve(this.response)}else{reject(this.response);};};};xhr.send();//发送请求});};fetch('get','http://120.78.164.247:8080/grade/findAll').then(({code,msg,extend})=>{console.log(code);console.log(msg);console.log(extend);}).catch(()=>{});//调用自己封装的fetchPromise的常用方法接下来我们看一下Promise中的一些基本用法1.Promise.prototype.then().then(function(){//success},functions(){//error});then方法定义在原型对象Promise.prototype上,也就是说Promise实例有一个thenmethod它的作用是给Promise实例添加状态变化时的回调函数。then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。then方法返回一个新的Promise实例(注意,不是原来的Promise实例)。所以可以采用链式写法,即在then方法之后再调用一个then方法。如果使用两个then方法,第一个回调函数完成后,会将返回结果作为参数传递给第二个回调函数。getJSON("/post/1.json").then(post=>getJSON(post.commentURL)).then(comments=>console.log("Resolved:",comments),err=>console.log("拒绝:",err));上面代码中,第一个then方法指定的回调函数返回了另一个Promise对象。这时第二个then方法指定的回调函数会等待新的Promise对象的状态改变。如果已解决,则调用funcA,如果状态变为拒绝,则调用funcB。2.Promise.prototype.catch()Promise.prototype.catch方法是.then(null,rejection)的别名,用于指定错误发生时的回调函数。一般来说,不要在then方法函数中定义Reject状态的回调(也就是then的第二个参数),一律使用catch方法。varpromise=newPromise(function(resolve,reject){reject(newError('test'));});promise.catch(function(error){console.log(error);});Promiseobjecterror具有“冒泡”的性质,并向后传递直到被捕获。也就是说,错误总是会被下一个catch语句捕获。3.Promise.all()Promise.all方法用于将多个Promise实例包装成一个新的Promise实例。varp=Promise.all([p1,p2,p3]);上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3是Promise实例,p的状态由p1、p2、p3决定,分为两种情况。只有当p1、p2和p3的状态成立时,p的状态才会成立。此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。只要p1、p2、p3中的一个被拒绝,p的状态就变成被拒绝,第一个被拒绝的实例的返回值就会传递给p的回调函数。4.Promise.race()Promise.race方法同样将多个Promise实例包装成一个新的Promise实例。在下面的代码中,只要p1、p2、p3中的一个实例先改变状态,p的状态就会随之改变。第一个改变的Promise实例的返回值被传递给p的回调函数。varp=Promise.race([p1,p2,p3]);上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3是Promise实例,p的状态由p1、p2、p3决定,分为两种情况。只有当p1、p2和p3的状态成立时,p的状态才会成立。此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。只要p1、p2、p3中的一个被拒绝,p的状态就变成被拒绝,第一个被拒绝的实例的返回值就会传递给p的回调函数。5.Promise.resolve()方法将一个已有的对象转换为Promise对象,例如:varjsPromise=Promise.resolve($.ajax('/whatever.json'));根据参数的不同,方法的返回值也会发生变化:1.参数是一个Promise实例。Promise.resolve将返回这个实例而不做任何修改。2.参数是thenable对象。thenable对象是指具有then方法的对象。Promise.resolve方法会把这个对象转成Promise对象,然后马上执行thenable对象的then方法。3.参数不是有then方法的对象,或者根本不是对象。如果参数是一个原始值,或者是一个没有then方法的对象,Promise.resolve方法返回一个状态为Resolved的新Promise对象。4.直接返回一个Resolved状态的Promise对象,不带任何参数。需要注意的是,立即resolve的Promise对象是在本轮“事件循环”(eventloop)结束时,而不是在下一轮“事件循环”开始时。6.Promise.reject()Promise.reject(reason)方法也返回一个状态为rejected的新Promise实例。varp=Promise.reject('出错了');//等价于varp=newPromise((resolve,reject)=>reject('somethingwentwrong'));7.finally()finally方法用于指定是否将执行的操作与最终状态无关Promise对象。它以一个无论如何都必须执行的正常回调函数作为参数。下面是一个例子,服务端使用Promise处理请求,然后使用finally方法关闭服务端server.listen(0).then(function(){//runtest}).finally(server.停止);//关闭服务器使用小结Promise对象的使用大致可以分为以下几个步骤:1.构建一个promise对象letpromise=newPromise((resolve,reject)=>{//resolve()Unknown->成功//reject()未知->失败});2.执行promise.then(()=>{//成功回调}).catch(()=>{//失败回调});3、企业应用
