Skip to content
simen edited this page Dec 21, 2016 · 4 revisions

1. Overview

areq is a timeout controller for asynchronous requests with Promise defers (e.g., Q.defer()). It tackles the event listener registering and timeout rejection for you.


2. Installation

$ npm install areq --save


3. Usage

var Q = require('q'),
    Areq = require('areq'),
    EventEmitter = require('events');

var myEmitter = new EventEmitter(),
    areq = new Areq(myEmitter, 6000);   // timeout after 6 seconds

var fooAsyncReq = function (callback) {
    var deferred = Q.defer();

    areq.register('some_event', deferred, function (result) {
        if (result !== 'what_i_want') {
            areq.reject('some_event', new Error('Bad response.'));
        } else {
            areq.resolve('some_event', result);
        }
    });

    return deferred.promise.nodeify(callback);
};

fooAsyncReq(function (err, result) {
    if (err)
        console.log(err);
    else
        console.log(result);
});


4. APIs


new Areq(emitter[, areqTimeout])

Create an instance of Areq Class, which will be denoted as areq in this document.

Arguments

  1. emitter (EventEmitter): The emitter that emits the events for your listening to resolve the asynchronous responses.
  2. areqTimeout (Number, optional): The default timeout in milliseconds. If elapsed time from the moment of a request sending out has reached this setting, the request will be rejected with a timeout error. If it is not given, a value of 30000 ms will be used as the default.

Returns:

  • (Object): Returns an instance of Areq class.

Example

var Areq = require('areq');

var areq = new Areq(foo_nwk_controller);
// foo_nwk_controller is your event emitter to dispatch messages from lower layer



register(evt, deferred, listener[, time])

Register an unique event to listen for the specific response coming from the emitter.

Arguments

  1. evt (String): The unique event according to the specific response.
  2. deferred (Object): The defer object used in your method.
  3. listener (Function): The event listener. With areq, now you should use areq.resolve(evt, value) and areq.reject(evt, err) instead of using deferred.resolve(value) and deferred.reject(err). areq.resolve() and areq.reject() will take care of the listener deregistering and timeout cleaning for you.
  4. time (Number, optional): Register this areq with a timeout in milliseconds. A default value of 30000 will be used if not given.

Returns:

  • (None)

Example

var myAreqMethod  = function () {
    var deferred = Q.defer(),
        transId = my_nwk_controller.nextTransId(),
        eventToListen = 'AF:incomingMsg:' + transId;
        // event to listner maybe like this: AF:incomingMsg:172, 
        // where 172 is a unique transection id

    areq.register(eventToListen, deferred, function (result) {
        if (result !== 'what_i_want')
            areq.reject(eventToListen, new Error('Bad response.'));
        else
            areq.resolve(eventToListen, result);
    }, 10000);  // if this reponse doesn't come back wihtin 10 secs, 
                // your myAreqMethod() will be rejected with a timeout error 

    return deferred.promise.nodeify(callback);
};

// now call your myAreqMethod() somewhere in the code
// (1) with thenable style
myAreqMethod().then(function (rsp) {
    console.log(rsp);
}).fail(function (err) {
    console.log(err);
}).done();


// (2) with err-back style
myAreqMethod(function (err, rsp) {
    if (err)
        console.log(err);
    else
        console.log(rsp);
});



resolve(evt, value)

Resolve the received response if the response is exactly that you need.

Arguments

  1. evt (String): The unique event according to the specific response.
  2. value (Depends): The value to be resolved.

Returns:

  • (None)

Example

var myAreqMethod  = function () {
    var deferred = Q.defer(),
        transId = my_nwk_controller.nextTransId(),
        eventToListen = 'ZDO:incomingMsg:' + transId;

    areq.register(eventToListen, deferred, function (rsp) {
        if (rsp.status !== 0 && rsp.status !== 'SUCCESS')
            areq.reject(eventToListen, new Error('Bad response.'));
        else
            areq.resolve(eventToListen, rsp);
    });  // if this reponse doesn't come back wihtin default 30 secs, 
         // myAreqMethod() will be rejected with a timeout error 

    return deferred.promise.nodeify(callback);
};

// now call your myAreqMethod() somewhere in the code
myAreqMethod(function (err, rsp) {
    if (err)
        console.log(err);
    else
        console.log(rsp);
});



reject(evt, err)

Reject the received response if the response is not what you need.

Arguments

  1. evt (String): The unique event according to the specific response.
  2. err (Error): The reason why you reject this response.

Returns:

  • (None)

Example

See the exmaple given with resolve() method.



getRecord(evt)

Get record of the given event name. Returns undefined if not found.

Arguments

  1. evt (String): The unique event according to the specific response.

Returns:

  • (Object): The record in the registry.

Example

areq.getRecord('AF:incomingMsg:6:11:162');  // { deferred: xxx, listener: yyy }

areq.getRecord('No_such_event_is_waiting');  // undefined



isEventPending(evt)

Checks if the event is pending. Usually, if you find someone is pending over there, it is suggested to change a new event to listen to. For example, get another transection id to make a new event name for your request.

Arguments

  1. evt (String): The unique event according to the specific response.

Returns:

  • (Boolean): Return true is the given event is pending, otherwise returns false.

Example

areq.isEventPending('AF:incomingMsg:6:11:161');  // true
areq.isEventPending('AF:incomingMsg:6:11:162');  // false