当前位置: 首页 > 后端技术 > Node.js

JavaScript中的异步,await

时间:2023-04-03 18:02:33 Node.js

能省吗?一直以来,困扰我的一个问题就是JavaScript是否可以实现不带await的异步。我今天终于想通了。之前就知道在JavaScript中同步获取异步执行的结果,必须使用await;在for循环中,如果不使用Promise.All,异步将不起作用。但是每次需要等待执行结果的时候,都需要带上async和await。我觉得太麻烦了,也不好看。把这两个字的写法背下来就好了。如果不背,每拼错一次,思路就会被打断,突然冒出这样的字,很不美观。所以我一直致力于解决这个问题,作为一个经常以造轮子为荣的程序员,我觉得为改变JavaScript做出一点小小的贡献是我的责任。请看下面的代码。consttrans=require('node-google-translate-skidz');functiontranslate(str,strEn,tarEn){letp=()=>{returnnewPromise((resolve,reject)=>{trans({text:str,source:strEn?strEn:'zh',目标:tarEn?tarEn:'en'},function(result){resolve(result.translation)});})}letan=async()=>{letb=awaitp()console.log(b);}returnan()//console.log(b)}letc=translate('Chinese')console.log('c',c)这段代码可能是我能想到的解决异步问题的最佳方案,答案还是没有成功。但是我终于知道为什么在JavaScript中,不管你怎么包装,无论你使用什么技术,你都无法真正避免async和await。查看调用translate方法的地方,调用后打印翻译结果。这样做的目的当然是希望打印结果。如果打印的是Promise{},表示不等待直接执行。为了达到有结果后打印的目的,我巧妙的在translate方法中封装了一个async()=>{await},然后让translate返回await执行的结果。但是这个方法什么也做不了,因为最后打印出来的结果还是我想尽量避免的。为什么?因为忘记了async只作用于函数,也就是说async是有scope的。我执行完letc=translate('Chinese')方法后,因为没有告诉编译器translate需要await(我以为translate已经实现了async和await,那么translate会自动等待执行结果返回。但是因为作用域的存在,translate的内部作用域无法影响translate方法的执行级别。),所以编译器还是直接执行console.log('c',c),即打印Promise{<待处理>}。通过引入scope的概念,方法体中的async和await不能让方法调用的层次也变成async和await。你大概能理解为什么JavaScript中不能省略asynchronousawait。