在回调函数中处理数据

时间:2016-08-09 14:48:07

标签: javascript node.js asynchronous callback waterfall

我有一个嵌套函数,它执行一些I / O并在完成结果数据后调用回调。像这样:

function getStatus(returnCallback, errorCallback) {
   sendRequest('someData', returnCallback, errorCallback)
}

其中sendRequest()是一个与硬件交互并使用从硬件或errorCallback获得的数据调用returCallback的函数,以防出现问题。 我现在的问题是,硬件返回的数据是一个非常长的字符串,由代表不同参数的不同数字组成。我想要做的是操纵给予returnCallback的数据,并使用每个参数的属性创建和对象。有没有办法做到这一点?我已经尝试过使用async.waterfall

function getStatus(returnCallback, errorCallback) {
        let returnArray = {};
        async.waterfall([
            function (callback) {
                sendRequest('someData', callback, errorCallback);
            },
            function (data, callback) {
                returnArray.statusBits = data.slice(0, 6);
                returnArray.faultBits = data.slice(7, 13);
                returnArray.alertBits = data.slice(14, 20);
                returnArray.pumpRotationSpeed = parseInt(data.slice(21, 26));
                returnArray.motorPower = parseInt(data.slice(27, 31));
                returnArray.frequencyConverterTemperature = parseInt(data.slice(36, 39));
                returnArray.pumpOperationTime = parseInt(data.slice(44, 48));
                callback(null, returnArray)
            }
        ], returnCallback(returnArray));

但这没有任何作用。因为它看起来瀑布中的第二个功能从未被调用过。这可能是因为第一个函数的回调在瀑布中没有按预期结构化,它返回回调(数据)而不是回调(null,数据)

2 个答案:

答案 0 :(得分:1)

async.waterfall回调中,第一个参数是error,你也应该在退出函数之前等待瀑布的结束。正确的代码是:

function getStatus(returnCallback, errorCallback) {
    let returnArray = {};
    async.waterfall([
        function (callback) {
            //First step
            sendRequest('someData', function (data) {
                //Everything is fine, continue
                callback(null, data);
            }, function (error) {
               //Error, skip all remaining step, and handle the error
                callback(error);
            });
        },
        function (data, callback) {
            //Second step
            returnArray.statusBits = data.slice(0, 6);
            returnArray.faultBits = data.slice(7, 13);
            returnArray.alertBits = data.slice(14, 20);
            returnArray.pumpRotationSpeed = parseInt(data.slice(21, 26));
            returnArray.motorPower = parseInt(data.slice(27, 31));
            returnArray.frequencyConverterTemperature = parseInt(data.slice(36, 39));
            returnArray.pumpOperationTime = parseInt(data.slice(44, 48));
            callback(null, returnArray)
        }
    //In normal case, error will be null, and the param will be the last passed to the callback of the last step
    ], function (error, returnArray) {
        //If there is a error (like error in step 1)
        if(error) {
            //Handle the error
            errorCallback(error);
        } else {
            //No error, continue with the normal callback
            returnCallback(returnArray);
        }
    });
}

答案 1 :(得分:0)

你想做的是

  

操纵给予returnCallback的数据并创建和   具有每个参数的属性的对象。

你有

function getStatus(returnCallback, errorCallback) {
   sendRequest('someData', returnCallback, errorCallback)
}

如果我明白你要做什么,

function getStatus(function(err, status) {
   if (err) return new Error('Something went wrong');
   else  sendRequest(status);
}
//get what you need here
var status = ... )

这里,getStatus函数通过在并行进程中执行回调函数开始。 statuserr参数将作为占位符放置在内存中。与此同时,getStatus正在做他需要做的事情来检索你想要的状态并将其存储为变量。读取完成后,将结果放在并行进程的占位符内,然后执行完成。

这种异步方法来自于您正在读取硬件内部的数据,并且需要一些时间来检索它。同步方式会阻塞任务并等待每个步骤完成,而异步地,它允许不会在每一步都阻塞,而是在完成之前的任务时启动其他任务。