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

异步编程

时间:2023-03-27 01:49:59 JavaScript

同步与异步Synchronous:按代码顺序执行异步:先执行同步代码,完成后再执行异步代码//同步console.log("begin");functionoutput(){console.log("这是输出函数");}output();console.log("end");//输出//begin//这是输出函数//end//异步console.log("begin");setTimeout(functiontimer1(){console.log("timer1invoke");},3000);setTimeout(functiontimer2(){console.log("timer2invoke");setTimeout(functioninner(){console.log("inner调用");},1000);},1000);console.log("end");//输出//开始//结束//timer2调用//内部调用//timer1调用事件循环和消息队列:当代码执行到异步方法时,异步方法将被放入消息队列。所有同步方法执行完毕后,通过事件循环按入栈顺序从消息队列中读取方法执行。回调函数传入一个函数,表示任务执行后要做什么//callbackfunctionfunctionfoo(callback){setTimeout(function(){callback();},3000);}PromisePromise是你从中得到的一个对象可以获取异步操作的消息。三种状态:Pending(进行中)、Resolved(已完成)和Rejected(失败)。状态不受外界影响:只有异步操作的结果才能确定当前处于哪个状态,其他任何操作都不能改变这个状态。状态是不可逆的:Promise对象的状态变化只有两种可能:从Pending变成Resolved和从Pending变成RejectedPromise构造函数接受一个函数作为参数,它的两个参数是resolve和reject。constpromise=newPromise((resolve,reject)=>{resolve("true");reject("false");});承诺。然后((值)=>{console.log(value);},(error)=>{console.log(error);});此外,Promise对象提供了统一的接口,更容易控制异步操作??。然后在Promise实例状态改变时添加一个回调函数。then方法的第一个参数是Resolved状态的回调函数,第二个参数(可选)是Rejected状态的回调函数。functionadd(data,index){returnnewPromise((resolve,reject)=>{try{resolve(data*index);}catch(error){reject(newError(error));}});}add(10,1).then((value)=>{console.log(value);返回值;},(error)=>{console.log(error);}).then((value)=>{console.log(value+1);});catch用于指定发生错误时的回调函数。//thenpromise.then(function(data){//success},function(err){//error});//catchpromise.then(function(data){//success}).catch(function(err){//错误});上面代码中catch可以捕获调用链中的所有异常,then的第二个参数只能捕获上一步的异常。同时在我们的代码中使用catch更接近于try/catch操作,因此建议使用catch来处理异常,而不是一直依赖第二个参数then。该方法接受一个数组作为参数,用于将多个Promise实例包装成一个新的Promise实例。只有当所有Promise实例的状态都变为fulfilled时,最终的执行结果状态才会fulfill。只要有一个Promise实例被拒绝,执行结果就会变成被拒绝。此时会通过第一个被拒绝实例的返回值回调函数允许根据异步代码的调用顺序获取异步代码的执行结果letp1=setTimeout(functiontimer1(){console.log("p1");},1000);letp2=setTimeout(functiontimer1(){console.log("p2");},2000);letp3=setTimeout(functiontimer1(){console.log("p3");},3000);Promise.all([p1,p2,p3]);//输出//p1//p2//p3race也将多个Promise实例包装成一个新的Promise实例。与所有不同的是,只要一个实例状态发生变化,最终状态也会发生变化。第一个更改的Promise实例的返回值被传递给回调函数。resolve将现有对象转换为Promise对象finally用于指定将执行的操作,而不管Promise对象的最终状态如何。宏任务和微任务setTimeout的回调是宏任务,回调队列中排队的Promise的回调是微任务。Generator是一个状态机,在本轮调用结束时直接执行,封装了多个内部状态。函数关键字和函数名之间有一个星号函数体内使用yield语句来定义不同的内部状态function*helloWorld(){yield"hello";产生“世界”;返回“结尾”;}varhw=helloWorld();console.log(hw.next());//{value:'hello',done:false}console.log(hw.next());//{value:'world',done:false}console.log(hw.next());//{value:'ending',done:true}console.log(hw.next());//{value:undefined,done:true}async/awaitGenerator的语法糖功能。varfs=require("fs");varreadFile=function(fileName){returnnewPromise(function(resolve,reject){fs.readFile(fileName,function(error,data){if(error)reject(error);resolve(data);});});};//letgen=function*(){//varf1=yieldreadFile("./users.json");//varf2=yieldreadFile("./posts.json");////console.log(f1.toString());////console.log(f2.toString());//};//varx=gen();//console.log(x.next().value.then((value)=>console.log(value.toString())));//console.log(x.next().value.then((value)=>console.log(value.toString())));//console.log(x.next());//console.log(x.next());异步函数asyncReadFile(){varf1=awaitreadFile("./users.json");varf2=awaitreadFile("./posts.json");console.log(f1.toString());console.log(f2.toString());}asyncReadFile();async函数就是将Generator函数的星号(*)替换成async,将yield替换成await,仅此而已。