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

JavaScript中,async+await和直接同步执行有什么区别?什么意思?

时间:2023-03-28 12:27:56 HTML

你必须先明白以下几个要点:你要将JS中的执行分为两种。首先是它必须由JS线程执行,比如做一些计算文件MD5值的事情。一般没人写异步,没有好处,都是同步计算。第二种不是由JS线程执行,而是JS将任务提交给它,然后等待它完成并将结果返回给自己。比如你调用浏览器接口从网上下载图片。这个时候你的JS线程把任务提交给浏览器,然后等待浏览器把结果返回给你。完成工作的是浏览器,而不是您的JS线程。非工作情况,就得用异步写,否则执行效率低,页面卡死。JS动态加载。之前用的方法是callback,就是在调用接口的时候同时传递一个函数,告诉浏览器或者有人在任务完成的时候调用这个函数,然后我们把一些需要的东西放在函数里面在可以处理任务之前完成。比如让浏览器下载图片,我们把显示图片放在函数里,这个函数叫做回调函数。你常见的onload和onready是什么意思。functiondownload(callback){//这个下载需要5秒letfile="Iamafile"setTimeout(()=>callback(file),5000)}console.log("started~")console.log("先去下一张图~")//下载完成告诉我,我不等你download((file)=>{console.log("下载完成:"+file)console.log("DisplayPicture")})console.log("Goingtodootherthings~")//开始执行了~//先去下一张图~//去干别的事~//5秒后......//下载完成:我是一个文件//显示图片但是如果我要下载一个文件,它的下载链接保存在文件A中,文件A的下载链接保存在文件中B,文件B的下载链接保存在C文件中。然后我要先下载C文件,等C下??载得到B下载B文件的链接,再等B下载A文件,最后在中得到我的文件下载链接A文件。(没有这种傻逼的场景,但是多个任务根据上一个任务的完成情况依次处理的情况还是很常见的。)这样会形成多层嵌套的回调,称为回调地狱。functiondownload(callback){//这个下载需要5秒letfile="Iamafile"setTimeout(()=>callback(file),5000)}console.log("started~")console.log("先去下一个文件~")//下载完成告诉我,我不等你download((file)=>{console.log("C下载完成")console.log("GetBlink")download((file)=>{console.log("DownloadBcompleted")console.log("GetAlink")download((file)=>{console.log("下载A完成")console.log("获取最终文件的链接")download((file)=>{console.log("下载最终文件")})})})})console.log("DootherthingsGo~")于是,async+await出现了,它让我们可以用一种看起来像同步的方式来编写异步程序。不要害怕async和await,你可以把它们理解为回调的语法糖,回调函数的内容就是await之后的部分。第一段代码可以重写为:asyncfunctiondownload(){//本次下载需要5秒returnnewPromise((resolve,reject)=>{letfile="我是一个文件"setTimeout(()=>resolve(file),5000)})}asyncfunctionshowImage(){letfile=awaitdownload()//以下是之前回调函数的内容console.log("下载完成:"+file)console.log("显示图片")}console.log("开始执行~")console.log("先去下一张图~")showImage()console.log("去干别的事~")//开始执行~//先去下一张图~//去干别的事~//5秒后...//下载完成:我是一个文件//显示图片但一开始看起来有点复杂glance一点点,但是如果第二个程序重写呢?asyncfunctiondownload(){//这个下载用了5秒returnnewPromise((resolve,reject)=>{letfile="Iamafile"setTimeout(()=>resolve(file),5000)})}asyncfunctiongetFile(){letfile=awaitdownload()console.log("下载C完成")console.log("获取B的链接")file=awaitdownload()console.log("下载B完成")console.log("获取A的链接")file=awaitdownload()console.log("下载A完成")console.log("获取最终文件的链接")file=awaitdownload()console.log("下载A完成")console.log("最终文件下载完成")}console.log("开始执行~")console.log("先去下一张图~")getFile()console.log("去干别的事~")回调地狱消失了,我们只需在一个函数中完成所有操作,代码非常干净,async+await很棒