Skip to content

Commit

Permalink
Added loopUntilNoEvents() API to wait for aribtrary code.
Browse files Browse the repository at this point in the history
 * Existing APIs rely on explicit callback argument or predicate.
   This API does not require such prior information, just like
   how the nodejs 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 loopUntilNoEvents() to block "longer"
   than you want.
  • Loading branch information
achimnol committed Mar 30, 2016
1 parent 12e0127 commit de00325
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 3 deletions.
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@
process._tickDomainCallback();
binding.run();
};

module.exports.loopUntilNoEvents = function(){
process._tickDomainCallback();
binding.loopUntilNoEvents();
};

module.exports.loopWhile = function(pred){
while(pred()){
Expand Down
10 changes: 10 additions & 0 deletions src/deasync.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ NAN_METHOD(Run) {
info.GetReturnValue().Set(Nan::Undefined());
}

NAN_METHOD(LoopUntilNoEvents) {
Nan::HandleScope scope;
bool more = false;
do {
more = uv_run(uv_default_loop(), UV_RUN_ONCE);
} while (more);
info.GetReturnValue().Set(Nan::Undefined());
}

static NAN_MODULE_INIT(init) {
Nan::Set(target, Nan::New("run").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(Run)).ToLocalChecked());
Nan::Set(target, Nan::New("loopUntilNoEvents").ToLocalChecked(), Nan::GetFunction(Nan::New<FunctionTemplate>(LoopUntilNoEvents)).ToLocalChecked());
}

NODE_MODULE(deasync, init)
21 changes: 18 additions & 3 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ var sleep = deasync(function (timeout, done) {
setTimeout(done, timeout);
});

var sleep_without_cb_or_pred = function (timeout) {
setTimeout(function() { console.log('second'); }, timeout);
};

var request = deasync(function (url, done) {
http.get(url, function (res) {
res.on('error', done);
Expand All @@ -21,11 +25,22 @@ var request = deasync(function (url, done) {
}).on('error', done);
});


// Expected order: "first", "second", "third", "async1"
var t = setTimeout(function () {
console.log('async1');
}, 2000);
t.unref(); // should not make loopUntilNoEvents() to block
console.log('first');
sleep_without_cb_or_pred(1000);
deasync.loopUntilNoEvents();
console.log('third');
t.ref(); // should make loopUntilNoEvents() to block
deasync.loopUntilNoEvents();

// Expected order: ls -la, "async2", request
setTimeout(function () {
console.log('async');
console.log('async2');
}, 1000);

console.log(exec('ls -la'));
sleep(2000);
console.log(request('http://nodejs.org'));

0 comments on commit de00325

Please sign in to comment.