0

Edit: I know JS is asynchronous, I have looked over the How to Return thread. The issue I'm having is that going from "foo" examples to something specific = I'm not quite sure where to re-format this.

Also here is some context: https://github.com/sharkwheels/beanballs/blob/master/bean-to-osc-two.js

I have a question about returns in node. It might be a dumb question, but here goes. I have a function that connects to a socket, and gets OSC messages from processing:

var sock = dgram.createSocket("udp4", function(msg, rinfo) {

    try {

        // get at all that info being sent out from Processing.

        //console.log(osc.fromBuffer(msg));

        var getMsg = osc.fromBuffer(msg);
        var isMsg = getMsg.args[0].value;
        var isName = getMsg.args[1].value;
        var isAdd = getMsg.address;
        var isType = getMsg.oscType;

        // make an array out of it

        var isAll = [];
        isAll.push(isName);
        isAll.push(isMsg);
        isAll.push(isAdd);
        isAll.push(isType);

        // return the array 
        console.log(isAll);
        return isAll; 


    } catch (error) {
        console.log(error);
    }
});

Below I have the start of another function, to write some of that array to a BLE device. It needs name and characteristics from a different function. How do I get the below function to use isAll AND two existing parameters?

var writeToChars = function (name, characteristics) { // this is passing values from the BLE setup function

    // i need to get isAll to here. 
    // eventually this will write some values from isAll into a scratch bank. 


}

Thanks.

mishap_n
  • 578
  • 2
  • 10
  • 23
  • use promises to pass it back to your write chars? – Tim Jun 02 '15 at 04:43
  • This is one of the more common Javascript questions and I will attempt to find other duplicate questions/answers for you. Your callback function is asynchronous. That means it happens sometime LATER, long after your outer function has already returned. Thus, you can't return a value from the callback and expect it to get back to the outer function - the outer function is already done executing. – jfriend00 Jun 02 '15 at 04:43
  • possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](http://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Aaron Dufour Jun 02 '15 at 04:43
  • possible duplicate of [How to return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – jfriend00 Jun 02 '15 at 04:44
  • Any code that wants to use your asynchronous result has to be INSIDE the callback itself or in a function that is called from within the async callback because that is the only place that the data is available. You must program asynchronously. You cannot program synchronously and expect to use the async result after your async function. – jfriend00 Jun 02 '15 at 04:46
  • I know that JS is asynchronous. I know there has to be some kind of callback or restructure in there. I'm just not sure where in this particular setup to put the callback. – mishap_n Jun 02 '15 at 05:34

2 Answers2

0

async call in this case be written something like this. state can be maintained in the variables in closure if required. In this particular case - you can do without any state (isAll) as well.

var isAll;
var soc = dgram.createSocket('udp4', oncreatesocket);
function oncreatesocket(msg, rinfo)
{
    isAll = parseMessage(msg);
    writeData(isAll);
}
function parseMessage(msg) {
    ...
    // code to parse msg and return isAll
}
function writeData() {}

if the writeData is small enough function. It can be inside oncreatesocket without impacting the readability of the code.

Sushil
  • 5,265
  • 2
  • 17
  • 15
  • Ok. This makes sense, more than "foo", thank you. But...the writeData function needs isAll, AND two parameters that are passed from somewhere else. So, the other part how to get one function that receives parameters from two different places, I'm lost. I'll update my question because its probably not that clear. – mishap_n Jun 04 '15 at 00:13
  • I saw your code. you are dealing with async coding problem. I would suggest to think about problem in pure english. write it as algo and break it down to steps. 1) what all data is required. it has been got & kept as state in variables. 2) once all data is obtained it has been written. 3) all work happens in one of the callbacks - ur callbacks are noble event handlers, socket handler. u can break down code in various helper functions and they need to be invoked from these handlers. – Sushil Jun 04 '15 at 04:44
  • Alright. I'll scale it back and do some re-thinking. Thanks for your suggestions. – mishap_n Jun 04 '15 at 14:31
0

Alright. So I figured out what to do, at least in this scenario. I'm sure there is a better way to do this, but for now, this works.

I'm mapping an existing global array of peripherals into the write function, while passing the OSC message to it as a parameter. This solved my issue of "how do I get two pieces of information to the same place". It figures out which peripheral is which and writes a different value to each scratch bank of each peripheral accordingly. Leaving here for future reference.

var writeToBean = function(passThrough){

var passThrough = passThrough;

console.log("in Write to bean: ", passThrough);

_.map(beanArray, function(n){
    if(n.advertisement.localName === passThrough.name){

        //var name = n.advertisement.localName;

        n.discoverSomeServicesAndCharacteristics(['a495ff20c5b14b44b5121370f02d74de'], [scratchThr], function(error, services, characteristics){

            var service = services[0];
            var characteristic = characteristics[0];
            var toSend = passThrough.msg;

            console.log("service", service);
            console.log("characteristic", characteristic);

            if (toSend != null) {
                characteristic.write(new Buffer([toSend]), false, function(error) {
                    if (error) { console.log(error); }
                        console.log("wrote " + toSend + " to scratch bank 3");
                });
            }

            // not sure how to make the program resume, it stops here. No error, just stops processing. 

        });
    }       
});
}
mishap_n
  • 578
  • 2
  • 10
  • 23