emit方法是c 异步执行方法的吗

请问EventEmitter的事件是异步执行吗? - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
看了这篇帖子 回复里有提到EventEmitter实现异步 请问具体是怎么做到的
-----------------------------------
var util = require(“util”);
var events = require(“events”);//EventEmitter通过events模块来访问
function asyncEvent() {//新建一个类
events.EventEmitter.call(this);
util.inherits(asyncEvent, events.EventEmitter);//使这个类继承EventEmitter
asyncEvent.prototype.log = function(data) {//定义一个新方法
this.emit(“data”, data);//在此触发名为&data&事件
console.log(‘Hi’);
var s = new asyncEvent();
s.on(“data”, function(data,callback) {//注册监听器,监听名为&data&事
for(var i = 0; i & 1000000; i++);
console.log(‘Received data: &’ + data + ‘&’);
s.log(“Hi”); // Received data: &It works!&ss
-----------------------------------
比如上面这篇代码 我执行log, 然后log执行里面的emit, 但是我发现代码执行时里面那个console.log(“Hi”)比emit要后执行
也就是说他是等待emit执行完了再执行的. 请问如果我想让事件异步执行该怎么做,谢谢
你先把 ‘Hi’ 改成不一样的把,不然怎么区分啊?
命令行输出是
Recieved data: &Hi&
还是很好区分的
你可以使用 nextTick
EventEmitter 的 emit 其实是同步的
另外一点,如果有多个 callback 添加到监听器,最终会按照添加的顺序执行
var util = require('util');
var events = require('events');
function eventEmitter() {
events.EventEmitter.call(this);
util.inherits(eventEmitter, events.EventEmitter);
var ee = new eventEmitter();
ee.on('data', function(data) {
process.nextTick(function(){
console.log(data);
ee.emit('data', 'f1');
console.log('f2');
如果不介意的话可以看下我的
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的I'm having something of a hard time determining what is asynchronous and what is not while running CasperJS, what must be wrapped in then() statements, and what is going to be evaluated when.
I'll run into a problem somewhere that has to do with a fall-through break statement, variable scope, or the evaluate() statement, and I'll start wrapping all my code in then() statements... which turns out to not be the problem.
I notice that my code runs on two levels when I step through it, an evaluation level that parses the code, and then come the then() statements. Also, my print statements appear in a sometimes inexplicable order.
My question: how do these then() statements actually get queued? I've read the docs, and I sort of understand. I want to understand the rules and have some cut and dried ways to determine what is sync and what is async.
I've even read parts of a book on async coding, but nothing really seems to address CasperJS structure specifically. Any resources?
Also, what's best practice for where to put your then() statements? Should they be peppered liberally throughout, or should they be in the controlling main casper.begin() function that calls the others?
Thanks folks, I'm used to PHP.
解决方案 Rule of thumb: All CasperJS functions which contain the words then and wait are asynchronous. This statement has many exceptions.
What is then() doing?
CasperJS is organized as a series of steps that handle the control flow of your script. then() handles the many PhantomJS/SlimerJS event types that define the ending of a step. When then() is called, the passed function is put into a step queue which is a simply JavaScript array. If the previous step finished, either because it was a simple synchronous function or because CasperJS detected that specific events where triggered, the next step will began execution and repeat this until all steps are executed.
All those step functions are bound to the casper object, so you can refer to that object using this.
The following simple script shows two steps:
casper.start("", function(){
this.echo(this.getTitle());
The first step is an implicit asynchronous ("stepped") open() call behind start(). The start() function also takes an optional callback which itself is the second step in this script.
During the execution of the first step the page is opened. When the page is completely loaded, PhantomJS triggers the , CasperJS triggers its own
and continues with the next step. The second step is a simple completely synchronous function, so nothing fancy is happening here. When this is done, CasperJS exits, because there are no more steps to execute.
There is an exception to this rule: When a function is passed into the run() function, it will be executed as the last step instead of the default exit. If you don't call exit() or die() in there, you will need to kill the process.
How does then() detect that the next step has to wait?
Take for example the following example:
casper.then(function(){
this.echo(this.getTitle());
this.fill(...)
this.click("#search");
}).then(function(){
this.echo(this.getTitle());
If during a step execution an event is triggered that denotes the loading of a new page, then CasperJS will wait for the page load until executing the next step. In this case a click was triggered which itself triggered a
from the underlying browser. CasperJS sees this and suspends execution using callbacks until the next page is loaded. Other types of such triggers may be form submissions or even when the client JavaScript does something like its own redirect with window.open()/window.location.
Of course, this breaks down when we are talking about single page applications (with a static URL). PhantomJS cannot detect that for example a different template is being rendered after a click and therefore cannot wait until it is finished loading (this can take some time when data is loaded from the server). If the following steps depend on the new page, you will need to use e.g. waitUntilVisible() to look for a selector that is unique to the page to be loaded.
What do you call this API style?
Some people call it Promises, because of the way steps can be chained. Aside from the name (then()) and an action chain, that's the end of the similarities. There is no result that is passed from callback to callback through the step chain in CasperJS. Either you store your result in a global variable or add it to the casper object. Then there is only a limited error handling. When an error is encountered CasperJS will die in the default configuration.
I prefer to call it a Builder pattern, because the execution starts as soon as you call run() and every call before is only there to put steps into the queue (see 1st question). That is why it doesn't make sense to write synchronous functions outside of step functions. Simply put, they are executed without any context. The page didn't even began loading.
Of course this is not the whole truth by calling it a builder pattern. Steps can be nested which actually means that if you schedule a step inside of another step, it will be put into the queue after the current step and after all the other steps that where already scheduled from the current step. (That's a lot of steps!)
The following script is a good illustration of what I mean:
casper.on("load.finished", function(){
this.echo("1 -& 3");
casper.on("load.started", function(){
this.echo("2 -& 2");
casper.start('/');
casper.echo("3 -& 1");
casper.then(function() {
this.echo("4 -& 4");
this.then(function() {
this.echo("5 -& 6");
this.then(function() {
this.echo("6 -& 8");
this.echo("7 -& 7");
this.echo("8 -& 5");
casper.then(function() {
this.echo("9 -& 9");
casper.run();
The first number shows the position of the synchronous code snippet in the script and the second one shows the actual executed/printed position, because echo() is synchronous.
Important points:
Number 3 comes first
Number 8 is printed between 4 and 5
To avoid confusion and hard to find problems, always call asynchronous functions after the synchronous functions in a single step. If it seems impossible, split into multiple steps or consider recursion.
How does waitFor() work?
is the most flexible function in the wait* family, because every other function uses this one.
waitFor() schedules in its most basic form (passing only one check function and nothing else) one step. The check function that is passed into it, is called repeatedly until the condition is met or the (global) timeout is reached. When a then and/or onTimeout step function is passed additionally, it will be called in those cases.
It is important to note that if waitFor() times out, the script will stop execution when you didn't pass in the onTimeout callback function which is essentially an error catch function:
casper.start().waitFor(function checkCb(){
}, function thenCb(){
this.echo("inner then");
}, null, 1000).then(function() {
this.echo("outer");
What are other functions that are also asynchronous step functions?
As of 1.1-beta3 there are the following additional asynchronous functions that don't follow the rule of thumb:
Casper module: back(), forward(), reload(), repeat(), start(), withFrame(), withPopup()
Tester module:
If you're not sure look into the
whether a specific function uses then() or wait().
Are event listeners asynchronous?
Event listeners can be registered using casper.on(listenerName, callback) and they will be triggered using casper.emit(listenerName, values). As far as the internals of CasperJS are concerned, they are not asychronous. The asynchronous handling comes from the functions where those emit() calls lie. CasperJS passes most PhantomJS events simply through, so this is where those are asynchronous.
Can I break out of the control flow?
The control or execution flow is the way CasperJS executes the script. When we break out of the control flow, we need to manage a second flow (or even more). This will complicate the development and maintainability of the script immensely.
As example, you want to call an asynchronous function that is defined somewhere. Let's assume that there is no way to rewrite the function in such a way, that it is synchronous.
function longRunningFunction(callback) {
callback(data);
casper.start(url, function(){
longRunningFunction(function(data){
}).then(function(){
this.open(urlDependsOnFunResult???);
}).then(function(){
// do something with the dynamically opened page
Now we have two flows which depend on one another.
Other ways to directly split the flow is by using the JavaScript functions setTimeout() and setInterval(). Since CasperJS provides waitFor(), there is no need to use those.
Can I return to the CasperJS control flow?
When a control flow must be merged back into the CasperJS flow there is an obvious solution by setting a global variable and concurrently waiting for it to be set.
Example is the same as in the previous question:
casper.start(url, function(){
longRunningFunction(function(data){
}).waitFor(function check(){
// `undefined` is evaluated to `false`
}, function then(){
this.open(result.url);
}, null, 20000).then(function(){
// do something with the dynamically opened page
What is asynchronous in the test environment (Tester module)?
Technically, nothing is asynchronous in the tester module. Calling test.begin() simply executes the callback. Only when the callback itself uses asynchronous code (meaning test.done() is called asynchronously inside a single begin() callback), the other begin() test cases can be added to the test case queue.
That is why a single test case usually consists of a complete navigation with casper.start() and casper.run() and not the other way around:
casper.test.begin("description", function(test){
casper.start("").run(function(){
test.assert(this.exists("a"), "At least one link exists");
test.done();
It's best to stick to nesting a complete flow inside of begin(), since the start() and run() calls won't be mixed between multiple flows. This enables you to use multiple complete test cases per file.
When I talk about synchronous functions/execution, I mean a blocking call which can actually return the thing it computes.
本文地址: &
我有一个很难的东西确定什么是异步的,什么是不可以在运行CasperJS,哪些必须被包裹在那么()语句,以及正在发生的事情进行评估时我会碰到什么地方的问题,即有落空break语句,变量的作用域做,或评估()语句,我会着手结束我的所有code,然后在()语句...果然不是问题。我发现我的code在两个层面上运行时我逐句通过它,解析code的评估水平,然后拿出了当时()语句。另外,我的打印语句出现在一个有时会莫名的订单。我的问题:如何做到这些则()语句实际上得到排队?我读过的文档,而我有点明白了。我想了解这些规则,并有一些切割和干燥的方法来确定什么是同步的,什么是异步。我甚至看过一本书上的异步编码部分,但没有真正似乎专门解决CasperJS结构。任何资源?此外,什么是对的地方把你的话()语句的最佳实践?他们应该在整个宽松穿插,或者他们应该在调用其他人呢?控制主要casper.begin()函数谢谢乡亲们,我已经习惯了PHP。解决方案 经验法则: 其中包含单词然后和所有CasperJS功能等是异步的。的:此语句有很多例外。什么是则()在做什么? CasperJS被组织成一系列的处理脚本的控制流步骤。 则()处理多种PhantomJS /定义一个步骤的结局SlimerJS事件类型。当则()被调用时,传递函数被放入队列一步这是一个简单的JavaScript数组。如果previous一步完成,要么是因为它是一个简单的同步功能,或者是因为CasperJS检测,凡触发特殊事件,下一步将开始执行,直到执行所有步骤重复这一点。所有这些步骤中的功能被绑定到卡斯帕对象,所以你可以参考使用这个的对象。 下面的简单脚本显示了两个步骤:
casper.start(“”功能(){
this.echo(this.getTitle());})。跑(); 第一步是隐式异步(“阶梯”),后面 的open()调用start()。在的start()函数也有一个可选的回调这本身就是在这个脚本中的第二个步骤。在第一步骤中的页被打开的执行。当页面完全加载,PhantomJS触发,CasperJS触发其自己的并进行下一步继续。第二步是一个简单的完全同步的功能,所以没有什么花哨发生在这里。当这样做时,CasperJS退出,因为没有更多的步骤来执行。有一个例外:当一个函数被传递到的run()功能,它将作为最后一步,而不是默认的出口被执行。如果你不叫退出()或死()在那里,你将需要终止进程。 如何则()检测,下一步要等待?就拿下面的例子:
casper.then(函数(){
this.echo(this.getTitle());
this.fill(...)
this.click(“#搜索”);})。然后(函数(){
this.echo(this.getTitle());}); 如果一个步执行时触发一个事件,表示新页面的加载过程中,那么CasperJS将等待页面加载,直到执行下一个步骤。在这种情况下的点击触发本身引发了onNavigationRequested从底层浏览器事件。 CasperJS看到这个,直到下一个页面加载使用回调暂停执行。其他类型,比如触发器可能是表单提交,甚至当客户端的JavaScript确实像自己的重定向与 window.open() /
window.location的。当然,这打破了,当我们在谈论一个页面应用程序(使用一个静态的URL)。 PhantomJS无法检测到,例如不同的模板被点击后呈现的,所以不能等到它完成加载(当数据从服务器加载这可能需要一些时间)。如果下面的步骤取决于新页面上,您将需要使用例如 waitUntilVisible()来寻找一个选择所独有的加载页面。你怎样称呼这个API的风格?有些人把它承诺,因为这样的步骤,可以链接。除了名称(则())和一个动作链,那是相似的结束。有没有一个从回调穿过在CasperJS梯级链回调的结果。要么你保存你的结果在一个全局变量或将其添加到卡斯帕对象。那么只有一个有限的错误处理。当遇到一个错误CasperJS将在默认配置死亡。我preFER尽快你叫叫它Builder模式,因为开始执行的run()和每一个电话是只有在那里放步骤之前,到队列(见第1题)。这就是为什么它没有意义的写步骤功能外同步功能。简单地说,他们没有任何上下文中执行。该页面甚至没有开工负荷。当然,这并不是全部的真相被称这是一个生成器模式。步骤可以嵌套这实际上意味着,如果安排另一个步骤的内部的步骤,将当前步骤之后放入队列,并且其中,已经从当前步骤调度的所有其他步骤之后。 (这是一个很大的步骤!)下面的脚本是什么我的意思是一个很好的例子:
casper.on(“load.finished”功能(){
this.echo(“1
- →3”);});casper.on(“load.started”功能(){
this.echo(“2
- →2”);});casper.start('/');casper.echo(“3
- →1”);casper.then(函数(){
this.echo(“4
- →4”);
this.then(函数(){
this.echo(“5
- →6”);
this.then(函数(){
this.echo(“6
- →8”);
this.echo(“7
- 大于7”);
this.echo(“8
- →5”);});casper.then(函数(){
this.echo(“9
- > 9”);});casper.run(); 第一个数字表示同步code段的脚本的位置,第二个显示实际执行/打印的位置,因为回声()是同步的。要点: 3号至上 8号印4,5 之间 为了避免混淆,很难发现问题,随时拨打同步功能后异步函数在一个步骤。如果它似乎是不可能的,分裂成多个步骤或考虑递归。 如何 WAITFOR()工作? 具体函数使用则()或等待()。的事件监听器异步?事件侦听器可以使用 casper.on(listenerName,回调)注册,他们会使用 casper.emit触发(listenerName,价值观) 。至于CasperJS的内部担心,他们不是异步。异步处理从哪里来的发出()通话躺在功能。 CasperJS只需通过传递最PhantomJS事件,所以这就是那些都是异步的。我可以打出来的控制流的?控制或执行流程是CasperJS执行脚本的方式。当我们打出来的控制流,我们需要管理第二流(甚至更多)。这将极大脚本的开发和维护复杂化。为例,你要调用的某处定义的异步函数。让我们假设没有办法重写以这样的方式的功能,即它是同步的。 函数longRunningFunction(回调){
回调(数据);
...}VAR的结果;casper.start(URL,函数(){
longRunningFunction(功能(数据){
结果=数据;
});})。然后(函数(){
this.open(urlDependsOnFunResult ???);})。然后(函数(){
//做一些与动态打开页面})。跑(); 现在我们有互相依赖两个流。其他的方式来直接分割流是使用JavaScript函数的setTimeout()和的setInterval()。由于CasperJS提供 WAITFOR(),也没有必要使用这些。我可以回到CasperJS控制流?在控制流必须合并回CasperJS流有通过设置一个全局变量并同时等待它设置一个显而易见的解决方案。实施例是一样的在previous问题:
VAR的结果;casper.start(URL,函数(){
longRunningFunction(功能(数据){
结果=数据;
});})。WAITFOR(功能检查(){
返回结果; //`undefined`被评估为'FALSE`},然后函数(){
this.open(result.url);},空,20000)。然后(函数(){
//做一些与动态打开页面})。跑(); 什么是在测试环境(测试模块)异步?从技术上来说,没有什么是测试仪模块中的异步的。调用 test.begin()只是执行回调。只有当回调本身使用异步code(即 test.done()里面是一个开始()回调),其他开始()测试用例可以添加到测试用例队列中。这就是为什么一个测试用例通常包括一个完整的导航与 casper.start()和 casper.run(),而不是周围的其他方式:
casper.test.begin(“说明”,功能(测试){
casper.start(“”).RUN(函数(){
test.assert(this.exists(“一”),“至少一个存在链接”);
test.done();
});}); 这是最好坚持筑巢的内部)一个完整的流程开始(,因为开始()和运行()通话不会被多个流之间的混合。这使您可以使用每个文件的多个完整的测试用例。 注: 当我谈论的同步的功能/执行,我的意思是阻塞调用这实际上可以返回它计算的东西。
本文地址: &
扫一扫关注官方微信理解Node.JS的事件循环和线程池机制_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
理解Node.JS的事件循环和线程池机制
总评分4.3|
浏览量89387
用知识赚钱
阅读已结束,下载文档到电脑
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩2页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢Qt信号和槽的连接方式
Qt支持6种连接方式,其中3中最主要:
Qt::DirectConnection(直连方式)
当信号发出后,相应的槽函数将立即被调用。emit语句后的代码将在所有槽函数执行完毕后被执行。(信号与槽函数关系类似于函数调用,同步执行)
Qt::QueuedConnection(排队方式)
当信号发出后,排队到信号队列中,需等到接收对象所属线程的事件循环取得控制权时才取得该信号,调用相应的槽函数。emit语句后的代码将在发出信号后立即被执行,无需等待槽函数执行完毕。(此时信号被塞到信号队列里了,信号与槽函数关系类似于消息通信,异步执行)
Qt::AutoConnection(自动方式)
Qt的默认连接方式,如果信号的发出和接收这个信号的对象同属一个线程,那个工作方式与直连方式相同;否则工作方式与排队方式相同。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 c 异步执行某个方法 的文章

 

随机推荐