Skip to content

Commit 393657d

Browse files
committed
Added loopUntilNoMoreEvents() API to wait for aribtrary code.
* Existing APIs rely on explicit callback argument or predicate. This API does not require such prior information, just like how the node.js main loop continues or terminates. * To use this API to block for a specific region of code, you should take care of other existing callbacks using unref() and ref() methods to prevent them from making loopUntilNoMoreEvents() to block "longer" than you want.
1 parent 12e0127 commit 393657d

File tree

3 files changed

+43
-19
lines changed

3 files changed

+43
-19
lines changed

index.js

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
* Copyright 2014-2015 Abbr
66
* Released under the MIT license
77
*/
8-
8+
99
(function () {
10-
10+
1111
var fs = require('fs'),
1212
path = require('path'),
1313
binding;
14-
14+
1515
// Seed random numbers [gh-82] if on Windows. See https://github.com/laverdet/node-fibers/issues/82
1616
if(process.platform === 'win32') Math.random();
17-
18-
17+
18+
1919
// Look for binary for this platform
2020
var nodeV = 'node-' + /[0-9]+\.[0-9]+/.exec(process.versions.node)[0];
2121
var nodeVM = 'node-' + /[0-9]+/.exec(process.versions.node)[0];
@@ -50,27 +50,35 @@
5050
function cb(e, r) {
5151
err = e;
5252
res = r;
53-
done = true;
53+
done = true;
5454
}
5555
}
5656
}
57-
57+
5858
module.exports = deasync;
59-
59+
6060
module.exports.sleep = deasync(function(timeout, done) {
6161
setTimeout(done, timeout);
6262
});
63-
63+
6464
module.exports.runLoopOnce = function(){
6565
process._tickDomainCallback();
6666
binding.run();
6767
};
68-
68+
69+
module.exports.loopUntilNoMoreEvents = function(){
70+
var more = false;
71+
do {
72+
process._tickDomainCallback();
73+
more = binding.run();
74+
} while (more);
75+
};
76+
6977
module.exports.loopWhile = function(pred){
70-
while(pred()){
71-
process._tickDomainCallback();
72-
if(pred()) binding.run();
73-
}
78+
while(pred()){
79+
process._tickDomainCallback();
80+
if(pred()) binding.run();
81+
}
7482
};
7583

7684
}());

src/deasync.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ using namespace v8;
66

77
NAN_METHOD(Run) {
88
Nan::HandleScope scope;
9-
uv_run(uv_default_loop(), UV_RUN_ONCE);
10-
info.GetReturnValue().Set(Nan::Undefined());
9+
bool _more = uv_run(uv_default_loop(), UV_RUN_ONCE);
10+
v8::Local<v8::Boolean> more = Nan::New(_more);
11+
info.GetReturnValue().Set(more);
1112
}
1213

1314
static NAN_MODULE_INIT(init) {

test.js

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ var sleep = deasync(function (timeout, done) {
88
setTimeout(done, timeout);
99
});
1010

11+
var sleep_without_cb_or_pred = function (timeout) {
12+
setTimeout(function() { console.log('second'); }, timeout);
13+
};
14+
1115
var request = deasync(function (url, done) {
1216
http.get(url, function (res) {
1317
res.on('error', done);
@@ -21,11 +25,22 @@ var request = deasync(function (url, done) {
2125
}).on('error', done);
2226
});
2327

24-
28+
// Expected order: "first", "second", "third", "async1"
29+
var t = setTimeout(function () {
30+
console.log('async1');
31+
}, 2000);
32+
t.unref(); // should not make loopUntilNoEvents() to block
33+
console.log('first');
34+
sleep_without_cb_or_pred(1000);
35+
deasync.loopUntilNoEvents();
36+
console.log('third');
37+
t.ref(); // should make loopUntilNoEvents() to block
38+
deasync.loopUntilNoEvents();
39+
40+
// Expected order: ls -la, "async2", request
2541
setTimeout(function () {
26-
console.log('async');
42+
console.log('async2');
2743
}, 1000);
28-
2944
console.log(exec('ls -la'));
3045
sleep(2000);
3146
console.log(request('http://nodejs.org'));

0 commit comments

Comments
 (0)