⑴ Web前端面试指导(三十二):同步和异步有什么区别
同步就是发出请求后,等到服务器返回结果,才继续执行下一步,异步则是不等服务器返回,直接并行执行下一步,服务器返回结果会通过处理回调函数执行
⑵ springboot框架开发的rest api工程,异步请求方法同步调用执行,怎么做
1、controller本身就是单例的,非线程安全,多线程会共用对象
2、controller不要涉及业务层,从其属性来看,控制层来连接请求触发服务
3、根据需求,两种方法都可行,只要不在controller层处理业务;
4、如果三个方法都是需要返回数据的,建议各自写各自的controller层,清晰明白;其实,如果三个方法业务性质一样,也可以封装起来,通过参数判断具体执行那部分代码
⑶ 前端的Promise是干啥的
Promise是异步编程的一种解决方案,可以替代传统的解决方案--回调函数和事件。ES6统一了用法,并原生提供了Promise对象。作为对象,Promise有以下两个特点:
(1)对象的状态不受外界影响。
(2)一旦状态改变了就不会在变,也就是说任何时候Promise都只有一种状态。
可以通过Promise的构造函数创建Promise对象。
varpromise=newPromise(function(resolve,reject)setTimeout(function(){
console.log("helloworld");},2000);
});
Promise构造函数接收一个函数作为参数,该函数的两个参数是resolve,reject,它们由JavaScript引擎提供。其中resolve函数的作用是当Promise对象转移到成功,调用resolve并将操作结果作为其参数传递出去;reject函数的作用是单Promise对象的状态变为失败时,将操作报出的错误作为其参数传递出去。如下面的代码:
functiongreet(){varpromise=newPromise(function(resolve,reject){vargreet="helloworld";
resolve(greet);
});returnpromise;
}
greet().then(v=>{console.log(v);//*
})
上面的*行的输出结果就是greet的值,也就是resolve()传递出来的参数。
注意:创建一个Promise对象会立即执行里面的代码,所以为了更好的控制代码的运行时刻,可以将其包含在一个函数中,并将这个Promise作为函数的返回值。
Promise的then方法
promise的then方法带有以下三个参数:成功回调,失败回调,前进回调,一般情况下只需要实现第一个,后面是可选的。Promise中最为重要的是状态,通过then的状态传递可以实现回调函数链式操作的实现。先执行以下代码:
functiongreet(){varpromise=newPromise(function(resolve,reject){vargreet="helloworld";
resolve(greet);
});returnpromise;
}varp=greet().then(v=>{console.log(v);
})console.log(p);
⑷ js 如何判断是异步请求还是普通请求
这是根据请求时的参数来决定的啊,如果async为true就是异步请求,为false就是同步请求。也就是说,是否异步请求是由前端决定的,后台程序是不作区分一视同仁处理的。前端如果是以同步方式发出请求,它就会阻塞程序,等待后台返回数据再继续运行;而异步方式的话,就会立刻返回,继续执行其他代码,当后台返回数据时再以回调函数的形式进行处理。既然同步异步是由前端决定的,那么前端的js自然就知道如何来处理这个请求结果啦。
⑸ 前端开发中如何实现异步编程
异步编程其实很常见,特别是在出线Node.js之后,异步编程更是让很多开发者受益。那么回到最初的地方,传统的前端开发中如何实现异步编程呢?下面列举了js实现异步编程的四种方式。
方法一:使用回调函数
方法二:事件监听
可以定义一个事件,并为这个事件设定处理函数。这样只有当这个时间发生的情况下,对应的处理函数才会被执行。
方法三:事件的发布/订阅
这个模式在NodeJS以及其他JS框架中都有实现,是一个非常常用的异步编程方式。具体的原理及实现方法可以参考我之前的博客:http://blog.csdn.net/fareise/article/details/52198877《 Node中EventEmitter以及如何实现JavaScript中的订阅/发布模式》,里面有比较详细的解析。
方法四:Promise模式
ES6中提供了原生的Promise对象,这个模式最开始只是一个构想,后来由一些框架库实现。Promise对象代表了未来才会知道结果的事件。
Promise的基本思路就是,将需要异步执行的事件储存起来,然后根据异步事件之行后的结果状态执行下一步的操作。具体的Promise对象的原理和ES6中的使用方法将在下一篇文章中更加深入的进行介绍。
⑹ 关于外频和内存的异步和同步问题
没有必要换内存,因为你的内存没有任何问题.
内存的运行频率是和你的前端总线同步的.如FSB400 内存就266 FSB533 内存就是333 FSB800 内存就是400 的.如果异步可能会造成不稳定.我的电脑就是这样.我的是FSB533 我的DDR400 就会降到333 如果要超频我的电脑会没有声音.
一般来说SP2800装机的时候都会选择超频,SP2800 1.8GHZ,你去看一下你是不是1.8GHZ
内存异步需要主板的支持.
⑺ 怎么能让前端总线和内存同步
Front Side Bus,简写为FSB,前端总线
什么是前端总线?不是超频的方法之一,也不是用来超频的。
我们知道,电脑有许多配件,配件不同,速度也就不同。在286、386和早期的486电脑里,CPU的速度不是太高,和内存保持一样的速度。后来随着CPU速度的飞速提升,内存由于电气结构关系,无法象CPU那样提升很高的速度(就算现在内存达到400、533,但跟CPU的几个G的速度相比,根本就不是一个级别的),于是造成了内存和CPU之间出现了速度差异,这时就提出一个CPU的主频、倍频和外频的概念,外频顾名思义就是CPU外部的频率,也就是内存的频率,CPU以这个频率来与内存联系。CPU的主频就是CPU内部的实际运算速度,主频肯定是比外频高的,高一定的倍数,这个数就是倍频。举个例子,你从电脑垃圾堆里拣到一个被抛弃的INTEL 486 CPU,上面印着486 DX/2 66。这个486的CPU的主频是66MHZ,DX/2代表是2倍频的,于是算出CPU的外频是33MZ,也就是内存的工作频率,这同时也是前端总线FSB的频率。因为CPU是通过前端总线来与内存发生联系的,所以内存的工作频率(或者说外频也行)就是前端总线的频率。刚才这个垃圾堆里的486 CPU,前端总线的频率就是33MZ。这样的前端总线结构一直延续到486之后的奔腾(俗话说的586)、奔腾2、奔腾3,例如一颗奔3 933MHZ的CPU,外频133,也就是说它的前端总线是133MHZ,内存工作频率也是133。
到了奔腾4年代,内存和CPU的工作模式发生了改变,前端总线的概念也变得有些复杂。奔腾4 CPU采用了Quad Pumped(4倍并发)技术,该技术可以使系统总线在一个时钟周期内传送4次数据,也就是传输效率是原来的4倍,相当于用了4条原来的前端总线来和内存发生联系。在外频仍然是133MHZ的时候,前端总线的速度增加4倍变成了133X4=533MHZ,当外频升到200MHZ,前端总线变成800MHZ,所以你会看到533前端总线的P4和800前端总线的P4,就是这样来的。他们的实际外频只有133和200,但由于人们保留了以前老的概念——前端总线就是外频,所以习惯了这样的叫法:533外频的P4和800外频的P4。其实还是叫533前端总线或533 FSB的P4比较合适。
那内存的情况怎么样呢?外频不完全等于前端总线了,那外频还等于内存的频率吗?内存发展到了DDR,跟原来相比,一个时钟周期内可以传送比原来多一倍的数据,DDR就是DOUBLE DATA RATE的缩写,意思就是双倍的数据传输速率。在133MHZ的外频下,DDR的传输速度是266,外频提高到200MHZ的时候,DDR的传输速度是400,DDR266的内存和DDR400的内存就是这个意思。
再看一下现在外频、内存频率、CPU的前端总线的的关系。在以前P3的时候,133的外频,内存的频率就是133,CPU的前端总线也是133,三者是一回事。现在P4的CPU,在133的外频下,前端总线达到了533MHZ,内存频率是266(DDR266)。问题出现了,前端总线是CPU与内存发生联系的桥梁,P4这时候的前端总线达到533之高,而内存只有266的速度,内存比CPU的前端总线慢了一半,理论上CPU有一半时间要等内存传数据过来才能处理数据,等于内存拖了CPU的后腿。这样的情况的确存在的,845和848的主板就是这样。于是提出一个双通道内存的概念,两条内存使用两条通道一起工作,一起提供数据,等于速度又增加一倍,两条DDR266就有266X2=533的速度,刚好是P4 CPU的前端总线速度,没有拖后腿的问题。外频提升到200的时候,CPU前端总线变为800,两条DDR400内存组成双通道,内存传输速度也是800了。所以要P4发挥好,一定要用双通道内存,865以上的主板都提供这个功能。但845和848主板就没有内存双通道功能了。
刚才说的是INTEL P4的FSB概念,它的对手AMD的CPU有所不同。
旧的462针脚的AMD CPU,采用ev6前端总线,相当于外频的两倍,也就是133外频时,AMD 462脚的CPU的FSB是266,使用DDR266内存和他搭配就刚刚好,如果用两条DDR266做成双通道,虽然内存有533的传输速度,但对于266的FSB,作用不大,所以双通道内存对CPU的帮助不明显。
新的AMD 754/939 64位CPU,内部就集成了内存管理器(以前内存管理器在主板心片里),所以AMD 64位CPU的前端总线FSB频率与CPU实际频率一致。
★FSB只指CPU与北桥芯片之间的数据传输速率,又称前端总线。FSB=CPU外频*4。
这个参数指的就是前端总线的频率,它是处理器与主板交换数据的通道,既然是通道,那就是越大越好,现在主流中最高的FSB是800M,向下有533M、400M和333M等几种,它们价格是递减的。
FSB(或是FrontSideBus,前端总线)是超频最容易和最常见的方法之一。FSB是CPU与系统其它部分连接的速度。它还影响内存时钟,那是内存运行的速度。一般而言,对FSB和内存时钟两者来说越高等于越好。然而,在某些情况下这不成立。例如,让内存时钟比FSB运行得快根本不会有真正的帮助。同样,在AthlonXP系统上,让FSB运行在更高速度下而强制内存与FSB不同步(使用稍后将讨论的内存分频器)对性能的阻碍将比运行在较低FSB及同步内存下要严重得多。
FSB在Athlon和P4系统上涉及到不同的方法。在Athlon这边,它是DDR总线,意味着如果实际时钟是200MHz的话,那就是运行在400MHz下。在P4上,它是“四芯的”,所以如果实际时钟是相同的200MHz的话,就代表800MHz。这是Intel的市场策略,因为对一般用户来说,越高等于越好。Intel的“四芯”FSB实际上具有一个现实的优势,那就是以较小的性能损失为代价允许P4芯片与内存不同步运行。每个时钟越高的周期速度使得它越有机会让内存周期与CPU周期重合,那等同于越好的性能。 Front Side Bus,简写为FSB,前端总线
什么是前端总线?不是超频的方法之一,也不是用来超频的。
我们知道,电脑有许多配件,配件不同,速度也就不同。在286、386和早期的486电脑里,CPU的速度不是太高,和内存保持一样的速度。后来随着CPU速度的飞速提升,内存由于电气结构关系,无法象CPU那样提升很高的速度(就算现在内存达到400、533,但跟CPU的几个G的速度相比,根本就不是一个级别的),于是造成了内存和CPU之间出现了速度差异,这时就提出一个CPU的主频、倍频和外频的概念,外频顾名思义就是CPU外部的频率,也就是内存的频率,CPU以这个频率来与内存联系。CPU的主频就是CPU内部的实际运算速度,主频肯定是比外频高的,高一定的倍数,这个数就是倍频。举个例子,你从电脑垃圾堆里拣到一个被抛弃的INTEL 486 CPU,上面印着486 DX/2 66。这个486的CPU的主频是66MHZ,DX/2代表是2倍频的,于是算出CPU的外频是33MZ,也就是内存的工作频率,这同时也是前端总线FSB的频率。因为CPU是通过前端总线来与内存发生联系的,所以内存的工作频率(或者说外频也行)就是前端总线的频率。刚才这个垃圾堆里的486 CPU,前端总线的频率就是33MZ。这样的前端总线结构一直延续到486之后的奔腾(俗话说的586)、奔腾2、奔腾3,例如一颗奔3 933MHZ的CPU,外频133,也就是说它的前端总线是133MHZ,内存工作频率也是133。
到了奔腾4年代,内存和CPU的工作模式发生了改变,前端总线的概念也变得有些复杂。奔腾4 CPU采用了Quad Pumped(4倍并发)技术,该技术可以使系统总线在一个时钟周期内传送4次数据,也就是传输效率是原来的4倍,相当于用了4条原来的前端总线来和内存发生联系。在外频仍然是133MHZ的时候,前端总线的速度增加4倍变成了133X4=533MHZ,当外频升到200MHZ,前端总线变成800MHZ,所以你会看到533前端总线的P4和800前端总线的P4,就是这样来的。他们的实际外频只有133和200,但由于人们保留了以前老的概念——前端总线就是外频,所以习惯了这样的叫法:533外频的P4和800外频的P4。其实还是叫533前端总线或533 FSB的P4比较合适。
那内存的情况怎么样呢?外频不完全等于前端总线了,那外频还等于内存的频率吗?内存发展到了DDR,跟原来相比,一个时钟周期内可以传送比原来多一倍的数据,DDR就是DOUBLE DATA RATE的缩写,意思就是双倍的数据传输速率。在133MHZ的外频下,DDR的传输速度是266,外频提高到200MHZ的时候,DDR的传输速度是400,DDR266的内存和DDR400的内存就是这个意思。
再看一下现在外频、内存频率、CPU的前端总线的的关系。在以前P3的时候,133的外频,内存的频率就是133,CPU的前端总线也是133,三者是一回事。现在P4的CPU,在133的外频下,前端总线达到了533MHZ,内存频率是266(DDR266)。问题出现了,前端总线是CPU与内存发生联系的桥梁,P4这时候的前端总线达到533之高,而内存只有266的速度,内存比CPU的前端总线慢了一半,理论上CPU有一半时间要等内存传数据过来才能处理数据,等于内存拖了CPU的后腿。这样的情况的确存在的,845和848的主板就是这样。于是提出一个双通道内存的概念,两条内存使用两条通道一起工作,一起提供数据,等于速度又增加一倍,两条DDR266就有266X2=533的速度,刚好是P4 CPU的前端总线速度,没有拖后腿的问题。外频提升到200的时候,CPU前端总线变为800,两条DDR400内存组成双通道,内存传输速度也是800了。所以要P4发挥好,一定要用双通道内存,865以上的主板都提供这个功能。但845和848主板就没有内存双通道功能了。
刚才说的是INTEL P4的FSB概念,它的对手AMD的CPU有所不同。
旧的462针脚的AMD CPU,采用ev6前端总线,相当于外频的两倍,也就是133外频时,AMD 462脚的CPU的FSB是266,使用DDR266内存和他搭配就刚刚好,如果用两条DDR266做成双通道,虽然内存有533的传输速度,但对于266的FSB,作用不大,所以双通道内存对CPU的帮助不明显。
新的AMD 754/939 64位CPU,内部就集成了内存管理器(以前内存管理器在主板心片里),所以AMD 64位CPU的前端总线FSB频率与CPU实际频率一致。
★FSB只指CPU与北桥芯片之间的数据传输速率,又称前端总线。FSB=CPU外频*4。
这个参数指的就是前端总线的频率,它是处理器与主板交换数据的通道,既然是通道,那就是越大越好,现在主流中最高的FSB是800M,向下有533M、400M和333M等几种,它们价格是递减的。
FSB(或是FrontSideBus,前端总线)是超频最容易和最常见的方法之一。FSB是CPU与系统其它部分连接的速度。它还影响内存时钟,那是内存运行的速度。一般而言,对FSB和内存时钟两者来说越高等于越好。然而,在某些情况下这不成立。例如,让内存时钟比FSB运行得快根本不会有真正的帮助。同样,在AthlonXP系统上,让FSB运行在更高速度下而强制内存与FSB不同步(使用稍后将讨论的内存分频器)对性能的阻碍将比运行在较低FSB及同步内存下要严重得多。
FSB在Athlon和P4系统上涉及到不同的方法。在Athlon这边,它是DDR总线,意味着如果实际时钟是200MHz的话,那就是运行在400MHz下。在P4上,它是“四芯的”,所以如果实际时钟是相同的200MHz的话,就代表800MHz。这是Intel的市场策略,因为对一般用户来说,越高等于越好。Intel的“四芯”FSB实际上具有一个现实的优势,那就是以较小的性能损失为代价允许P4芯片与内存不同步运行。每个时钟越高的周期速度使得它越有机会让内存周期与CPU周期重合,那等同于越好的性能。
⑻ 在BIOS里怎么设置CPU外频与内存频率的同步和异步
主板不同各有差异,我的是技嘉的,CPU外频先把CPU HOST CLOCK CONTROL改为ENABLED,然后CPU HOST FREQUENCY(MHZ)就是外频,如现在200可改为233,慢慢一点点升,多了可能就不能开机了。内存频率在CPU英文的下面叫做SYSTEM MERORY MULTIPLIER,默认是AUTO,是同步,异步里面可改为2 或2.5或 3之类的数字。
⑼ 怎样用JS实现异步转同步
源起
小飞是一名刚入行前端不久的新人,因为进到了某个大公司,俨然成为了学弟学妹眼中'大神',大家遇到js问题都喜欢问他,这不,此时他的qq弹出了这样一条消息
"hi,大神在吗?我有个问题想问,现在我们的代码里面有这样的东西,可是得不到正确的返回结果
1234567functiongetDataByAjax () {return$.ajax(...postParam)}vardata = getDataByAjax()if(data) {console.log(data.info)}"哦,你这里是异步调用,不能直接获得返回值,你要把if语句写到回调函数中",小飞不假思索的说到,对于一个‘专业’的fe来说,这根本不是一个问题。
“可是我希望只是改造getDataByAjax这个方法,让后面的代码成立。”
“研究这个没有意义,异步是js的精髓,同步的话会阻塞js调用,超级慢的,但是你要一再坚持的话,用async:true就好了”
“不愧是大神,我回去立刻试一试,么么哒”
两天后,她哭丧着脸登上了qq
“试了一下你的方法,但是根本行不通,哭~~”
“别急,我看看你这个postParam的参数行吗”
"这是一个jsonp请求啊,老掉牙的东西了,,jsonp请求是没有办法同步的"
“我知道jsonp请求的原理是通过script标签实现的,但是,你看,script也是支持同步的呀,你看tags/attscriptasync.asp”
“额,那可能是jquery没有实现吧,哈哈”
“大神,你能帮我实现一个jsonp的同步调用方式嘛,拜托了(星星眼)”
虽然他有点奇怪jquery为什么没有实现,但是既然w3school的标准摆在那里,码两行代码又没什么,
额,运行起来结果竟然是undefined!w3cshool的文档竟然也不准,还权威呢,我看也不怎么着,小飞暗自想到。
“刚才试了一下,w3school文档上写的有问题,这个异步属性根本就是错的”
“可是我刚还试过一次这个,我确认是好的呀”
(有兴趣的同学可以实现以下两个js,并且加上async的标签进行尝试。)
“这个,我就搞不清楚了”,小飞讪讪的说到
对方已离线
抽象
关于这个问题,相信不只是小飞,很多人都难以解答。为什么ajax可以做到同步,但jsonp不行,推广到nodejs上,为什么readFile也可以做到同步(readFileSync),但有的库却不行。
(至于script的async选项我们暂时避而不谈,是因为现在的知识维度暂时还不够,但是不要着急,下文中会给出明确的解释)
现在,让我们以计算机科学的角度抽象这个问题:
我们是否可以将异步代码转化为同步代码呢?(ASYNCCALL => SYNCCALL)
既然是抽象问题,那么我们就可以不从工程角度/性能角度/实现语言等等等方面来看(同步比异步效率低下),每增加一个维度,复杂程度将以几何爆炸般增长下去。
首先,我们来明确一点,==在计算机科学领域==同步和异步的定义
同步(英语:Synchronization),指对在一个系统中所发生的事件(event)之间进行协调,在时间上出现一致性与统一化的现象。在系统中进行同步,也被称为及时(in time)、同步化的(synchronous、in sync)。--摘自网络
异步的概念和同步相对。即时间不一致,不统一
明确了这一点,我们可以借助甘特图来表示同步和异步
注意看我们标红的地方,如果你完成了小测验1,就会得到和这张图一致的顺序
==同步执行的代码片段必然在异步之前。==
所以,无论从理论还是实际出发,我们都不得不承认,在js中,把异步方法改成同步方法这个命题是水月镜花
哦对了,最后还需要解释一下最开始我们埋下的坑, 为什么jsonp中的async没有生效,现在解释起来真的是相当轻松,即document.appendChild的动作是交由dom渲染线程完成的,所谓的async阻塞的是dom的解析,而非js引擎的阻塞。实际上,在async获取资源后,与js引擎的交互依旧是push taskQueue的动作,也就是我们所说的async call
推荐阅读: 关于dom解析请大家参考webkit技术内幕第九章资源加载部分
峰回路转
相信很多新潮的同学已经开始运用切了async/await语法,在下面的语法中,getAjax1和console之间的具有同步的特性
1234asyncfunction() {vardata = await getAjax1()console.log(data)}讲完了event loop和异步的本质,我们来重新审视一下async/await。
老天,这段代码亲手推翻了==同步执行的代码片段必然在异步之前。== 的黄金定律!
惊不惊喜,意不意外,这在我们的模型里如同三体里的质子一样的存在。我们重新审视了一遍上面的模型,实在找不到漏洞,找不到任何可以推翻的点,所以真的必须承认,async/await绝对是一个超级神奇的魔法。
到这里来看我们不得不暂时放弃前面的推论,从async/await本身来看这个问题
相信很多人都会说,async/await是CO的语法糖,CO又是generator/promise的语法糖,好的,那我们不妨去掉这层语法糖,来看看这种代码的本质, 关于CO,读的人太多了,我实在不好老生常谈,可以看看这篇文章,咱们就直接绕过去了,这里给出一个简易的实现
/5800210.html
终于,我们发现了问题的关键,如果单纯的看wait生成器(注意,不是普通的函数),是不是觉得非常眼熟。这就是我们最开始提出的spinlock伪代码!!!
这个已经被我们完完全全的否定过了,js不可能存在自旋锁,事出反常必有妖,是的,yield和*就是表演async/await魔法的妖精。
generator和yield字面上含义。Gennerator叫做生成器,yield这块ruby,python,js等各种语言界争议很大,但是大多数人对于‘让权’这个概念是认同的(以前看到过maillist上面的争论,但是具体的内容已经找不到了)
扩展阅读---ruby元编程 闭包章节yield(ruby语义下的yield)
所谓让权,是指cpu在执行时让出使用权利,操作系统的角度来看就是‘挂起’原语,在eventloop的语义下,似乎是暂存起当时正在执行的代码块(在我们的eventloop里面对应runPart),然后顺序的执行下一个程序块。
我们可以修改eventloop来实现让权机制
小测验2 修改eventloop使之支持yield原语
至此,通过修改eventloop模型固然可以解决问题,但是,这并不能被称之为魔法。
和谐共存的世界
实际上通过babel,我们可以轻松的降级使用yield,(在es5的世界使用让权的概念!!)
看似不可能的事情,现在,让我们捡起曾经论证过的
==同步执行的代码片段必然在异步之前。== 这个定理,在此基础上进行进行逆否转化
==在异步代码执行之后的代码必然不是同步执行的(异步的)。==
这是一个圈子里人尽皆知的话,但直到现在他才变得有说服力(我们绕了一个好长的圈子)
现在,让我们允许使用callback,不使用generator/yield的情况下完成一个wait generator相同的功能!!!
太棒了,我们成功的完成了generator到function的转化(虽然成本高昂),同时,这段代码本身也解释清楚了generator的本质,高阶函数,片段生成器,或者直接叫做函数生成器!这和scip上的翻译完全一致,同时拥有自己的状态(有限状态机)
推荐阅读 计算机程序的构造和解释 第一章generator部分
小测验3 实际上我们提供的解决方式存在缺陷,请从作用域角度谈谈
其实,在不知不觉中,我们已经重新发明了计算机科学中大名鼎鼎的CPS变换
Continuation-passing_style
最后的最后,容我向大家介绍一下facebook的CPS自动变换工具--regenerator。他在我们的基础上修正了作用域的缺陷,让generator在es5的世界里自然优雅。我们向facebook脱帽致敬!!egenerator
后记
同步异步 可以说是整个圈子里面最喜欢谈论的问题,但是,谈来谈去,似乎绝大多数变成了所谓的‘约定俗称’,大家意味追求新技术的同时,却并不关心新技术是如何在老技术上传承发展的,知其然而不知其所以然,人云亦云的写着似是而非的js。
==技术,不应该浮躁==
PS: 最大的功劳不是CO,也不是babel。regenerator的出现比babel早几个月,而且最初的实现是基于esprima/recast的,关于resprima/recast,国内似乎了解的并不多,其实在babel刚刚诞生之际, esprima/esprima-fb/acron 以及recast/jstransfrom/babel-generator几大族系围绕着react产生过一场激烈的斗争,或许将来的某一天,我会再从实现细节上谈一谈为什么babel笑到了最后~~~~