Meteor.wrapAsync - Stuck waiting in Callback?


#1

So I got the Meteor.wrapAsync working on one asynchronous function. The function was like this

asyncMasterOn = function(event, cb) {
    master.on(event, cb);
};
syncMasterOn = Meteor.wrapAsync(asyncMasterOn);

Super simple to use because that variable cb is an actual callback function. It all works perfectly.

Now I have a different asynchronous function that takes the form of this:

AsyncMasterReadCoils = function(coil_address,quantity,cb){
    master.readCoils(coil_address,quantity,cb)
};
SyncMasterReadCoils = Meteor.wrapAsync(AsyncMasterReadCoils);

The HUGE difference here is that the cb is not a callback function but an object that contains multiple callback functions (onComplete, onError, etc.). As seen below.

readCoils = function(coil_address, quantity, scanGroup) {
transaction = SyncMasterReadCoils(coil_address, quantity, {
        onComplete: function(err, response) {
            //if an error occurs, could be a timeout
            if (err) {
                console.error('Error Message on Complete w/ ScanGroup #:', scanGroup.groupNum)
                console.error(err.message);

            } else if (response.isException()) {
                console.log('Got an Exception Message. Scan Group #:', scanGroup.groupNum)
                console.log(response.toString());
                /*Read_Coils.find({
                    'groupNum': scanGroup.groupNum
                }).fetch()[0].errorCount;*/
                //syncReportModbusError(scanGroup);
            } else {
                console.log('Succesfully completed scanning of Scan Group #:', scanGroup.groupNum);
                console.log(response.getStates().map(Number));
                //THIS NEVER GETS RETURNED, STUCK HERE!
                return response.getStates().map(Number);
            }
        },
        onError: function() {

            console.error('Transaction Error? Error on readCoil, not complete! Scan Group #:', scanGroup.groupNum);
        }
    });
    transaction.on('timeout', function() {
        console.error('[transaction#timeout] Scan Group #:', scanGroup.groupNum);

    });
    //NEVER EXECUTED
    console.log('Inside readCoils at end');
};

What I am noticing is that the return statement doesnt get executed! I am stuck inside that onComplete callback. If I do not use Meteor.wrapAsync method then everything works just fine and I can return. However I have to use it (Meteor.wrapAsync) because I need to access my collections within one of these callbacks and I get those ugly ‘you must run in a Fiber’ errors.

I really hope someone can help me out! Thanks,

Jeremy


#2

So I have a good enough answer that I am going to implement. However I would still like to know whats going on here if anyone knows.

So the fix was to go through the documentation for the creator of this Async function and find another way of calling it without passing it an object of several callbacks. Ta da here its:

 transaction = master.readCoils(coil_address, quantity);
    AsyncTransactionOn = function(event, cb) {
        transaction.on(event, cb)
    };
    SyncTransactionOn = Meteor.wrapAsync(AsyncTransactionOn);

    SyncTransactionOn('complete', function(err, response) {
        //if an error occurs, could be a timeout
        if (err) {
            console.error('Error Message on Complete w/ ScanGroup #:', scanGroup.groupNum)
            console.error(err.message);

        } else if (response.isException()) {
            console.log('Got an Exception Message. Scan Group #:', scanGroup.groupNum)
            console.log(response.toString());

            reportModbusError(scanGroup);
        } else {
            console.log('Succesfully completed scanning of Scan Group #:', scanGroup.groupNum);
            console.log(response.getStates().map(Number));
            //return response.getStates().map(Number);
        }
    });

Now it seems to be returning correctly from the callback and I have access to Meteor collections. Huzzah!