当前位置: 首页 > Web前端 > JavaScript

es6series-promise,async,await

时间:2023-03-27 01:08:33 JavaScript

1.promise1.Promise是一种异步编程的解决方案,比传统的“回调函数和事件”方案更合理、更强大。异步操作的优点:链式操作降低编码难度(解决回调地狱问题)代码可读性显着增强对象不受外界影响。只有异步操作的结果才能确定当前处于哪个状态。(2)一旦状态发生变化,就不会再发生变化,并且随时可以得到这个结果(从pending到fulfilled,从pending到rejected).2.基本用法Promise对象是一个构造函数,用于生成Promise实例constpromise=newPromise(function(resolve,reject){});Promise构造函数接受一个函数作为参数,该函数的两个参数是resolve和rejectresolve函数的作用是将Promise对象的状态从“未完成”变为“成功”。reject函数的作用是将Promise对象的状态从“未完成”变为“失败”。then方法分别指定了resolved状态和rejected状态的回调函数。//resolve时调用第一个回调,reject时调用第二个回调。promise.then(function(value){//成功},function(error){//失败});promise.then(function(value){//成功}).catch(function(value){//失败});Promise创建后会立即执行,我们来看一个例子:(){console.log('resolved.');});console.log('Hi!');//Promise//Hi!//resolved.promise创建后立即执行,所以打印Promise,然后then方法的回调函数在当前脚本的所有同步任务执行完毕后执行,soresolved。终于输出了。3.实例方法Promise构造的实例有以下几个方法:then()catch()finally()then()then是实例状态改变时的回调函数,解析时调用第一个参数,第二个参数为in被拒绝时,调用then方法返回一个新的promise实例,可以链式调用。getJSON("/posts.json").then(function(json){returnjson.post;}).then(function(post){//...},function(err){console.log("rejected:",err);});catch()catch()方法是.then(null,rejection)或.then(undefined,rejection)的别名,用于指定错误发生时的回调函数constpromise=newPromise(function(resolve,reject){thrownewError('test');});promise.catch(function(error){console.log(error);});//Error:test//在上面的代码,promise抛出错误时,会被catch()方法指定的回调函数捕获。注意上面的写法等价于下面两种写法。//写法constpromise=newPromise(function(resolve,reject){try{thrownewError('test');}catch(e){reject(e);}});promise.catch(function(error){console.log(error);});//方式2constpromise=newPromise(function(resolve,reject){reject(newError('test'));});promise.catch(function(错误){console.log(错误);});对比上面两种写法,可以发现reject()方法的作用相当于抛出错误注意:(1)try...catch无法捕获无效的js代码try{===}catch(err){//不会执行console.log(err)}(2)try...catch无法捕获异步代码try{setTimeout(()=>{console.log(1)},1000)}catch(err){console.log(err)}getJSON('/posts.json').then(function(posts){//...}).catch(function(error){//处理getJSON和之前发生的错误回调函数运行console.log('发生错误!',error);});Promise对象的错误具有“冒泡”的性质,会向后传递,直到被捕获getJSON('/post/1.json').then(function(post){returngetJSON(post.commentURL);}).then(function(comments){//一些代码}).catch(function(error){//处理前三个Promises产生的错误});一般情况下,使用catch方法代替then()的第二个参数Promise对象抛出的错误error不会传递给外层代码,即不会有响应constsomeAsyncThing=function(){returnnewPromise(function(resolve,reject){//下面这行会报错,因为x没有声明resolve(x+2);});};浏览器运行到这一行,会打印错误提示ReferenceError:xisnotdefined,但是不会退出catch()方法中的进程,可以再次抛出错误,后面被catch方法捕获(再写一个catch方法来捕获异常)constsomeAsyncThing=function(){returnnewPromise(function(resolve,reject){//下面这行会报错,因为x没有声明resolve(x+2);});};someAsyncThing().then(function(){returnsomeOtherAsyncThing();}).catch(function(error){console.log('ohno',error);//下面这行会报错,因为y没有declarey+2;}).then(function(){console.log('carryon');});//哦不[ReferenceError:xisnotdefined]finally()finally()方法是用来指定Promise对象是否为finallyPromise.then(result=>{···}).catch(error=>{···}).finally(()=>{···});finally方法总是会返回原始值。//resolve的值为undefinedPromise.resolve(2).then(()=>{},()=>{})//resolve的值为2Promise.resolve(2).finally(()=>{}){})//reject的值为undefinedPromise.reject(3).then(()=>{},()=>{})//reject的值为3Promise.reject(3).finally(()=>{})4.ConstructorPromise构造函数有以下方法:all()race()allSettled()resolve()reject()try()all()all()方法用于将多个Promise实例包装成一个新的Promise实例constp=Promise.all([p1,p2,p3]);p的状态由p1,p2,p3决定,分为两种情况。(1)只有当p1、p2和p3的状态成立时,p的状态才会成立。此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。(2)只要p1、p2、p3其中之一被拒绝,p的状态就变成被拒绝。这时候第一个被拒绝的实例的返回值就会传递给p的回调函数。作为参数的promise实例定义了catch方法,发生rejected时不会触发promise.call的catch方法。如果没有定义catch方法,将调用Promise.all()的catch方法。constp1=newPromise((resolve,reject)=>{resolve('hello');}).然后(结果=>结果)。抓住(e=>e);constp2=newPromise((resolve,reject)=>{thrownewError('报告错误');}).then(result=>result).catch(e=>e);Promise.all([p1,p2]).then(result=>console.log(result)).catch(e=>console.log(e));//["hello",Error:报错]5.使用场景(1)将图片的加载写成Promise,一旦加载完成,Promise的状态发生变化constpreloadImage=function(path){returnnewPromise(function(resolve,reject){constimage=newImage();image.onload=resolve;image.onerror=reject;image.src=path;});};(2)当下一个异步请求依赖于上一个请求的结果时,我们也可以通过链式操作友好地解决问题(3)将多个请求合并在一起,汇总所有请求结果II.async11.介绍async函数的返回值是一个Promise对象。更进一步,async函数可以看做是多个异步操作封装到一个Promise对象中,await命令是内部then命令的语法糖。2.语法asyncfunctionname([param[,param[,...param]]]){statements}name:函数名。param:传递给函数的参数名称。statements:函数体语句。async后面跟一个函数,不能跟其他字符(比如数字,字符串等)3.基本用法async函数返回一个Promise对象,可以使用then方法添加回调函数。异步函数helloAsync(){返回“helloAsync”;}console.log(helloAsync())//Promise{:"helloAsync"}helloAsync().then(v=>{console.log(v);//helloAsync})中可能有await表达式异步功能。async函数执行时,如果遇到await,会先暂停执行。触发的异步操作完成后,将恢复执行异步函数,并返回解析后的值。await关键字仅在异步函数中可用。如果在async函数体之外使用await,只会出现语法错误。functiontestAwait(){returnnewPromise((resolve)=>{setTimeout(function(){console.log("testAwait");resolve();},1000);});}//等同于异步函数testAwait(){awaitnewPromise((resolve)=>{setTimeout(function(){console.log("testAwait");resolve();},1000);});}异步函数helloAsync(){awaittestAwait();console.log("helloAsync");}helloAsync();//testAwait//helloAsync异步函数会返回一个promise,status值为resolved1,在async函数中写入return,那么Promise对象resolve的值为undefined2,rerun的值作为resolved值3.await1。引入await后跟一个返回新promise并执行它的函数。await只能放在异步函数中2.语法[return_value]=awaitexpression;表达式:一个Promise对象或任何要等待的值。3.基本用法await命令后面跟着一个Promise对象,返回该对象的结果。如果不是Promise对象,直接返回对应的值asyncfunctionf(){//等同于//return123;returnawait123;}f().then(v=>console.log(v))//123awaitcommand后面跟一个Promise对象,后面也可以跟其他值,比如字符串,布尔值,数字,和普通功能。functiontestAwait(){console.log("testAwait");}asyncfunctionhelloAsync(){awaittestAwait();console.log("helloAsync");}helloAsync();//testAwait//helloAsyncawait因人而异表达式的处理方式:Promise对象:await暂停执行,等待Promise对象解析,然后恢复执行async函数并返回解析后的值。非Promise对象:直接返回对应的值。如果任何await语句后面的Promise对象被拒绝,整个async函数的执行将被中断。asyncfunctionf(){awaitPromise.reject('发生错误');等待Promise.resolve('你好世界');//不会被执行}f().then().catch()//catch捕捉异常如果想让前面的异步操作失败,不要打断后面的异步操作1.使用try..catch2,await后面的Promise对象后跟一个catch方法来处理之前可能发生的错误。四、注意事项1、对于多个await命令后的异步操作,如果没有后续关系,最好让它们同时触发。letfoo=awaitgetFoo();letbar=awaitgetBar();//写1let[foo,bar]=awaitPromise.all([getFoo(),getBar()]);//写2letfooPromise=getFoo();letbarPromise=getBar();letfoo=awaitfooPromise;letbar=awaitbarPromise;2.await命令只能在异步函数中使用。如果用在普通函数中,会报错//错误asyncfunctionhh(){setTimeout(()=>{awaitb()},1000)}//正确写functionhh(){setTimeout(async()=>{awaitb()},1000)//awaitfollowedbyWithasync}4.思考题console.log('scriptstart')asyncfunctionasync1(){console.log('async1start')awaitasync2()console.log('async1end')return'asyncthen'}asyncfunctionasync2(){console.log('async2end')}async1()setTimeout(function(){console.log('setTimeout')},0)async1().then(function(message){console.log(message)})newPromise(resolve=>{console.log('Promise')resolve()}).then(function(){console.log('promise1')}).then(function(){console.log('promise2')})console.log('脚本结束')