0

I am facing following issue:

I am calling in foreach cycle following browse function. When the rb.wsc.browse(symbol) is called the program do some WebSocket request and when the message is returned the event is emmited. The problem is that I always get the same browseData even when I know that the event is emited with different one. I think that this is closure issue, but I don't know how to solve it.

function browse(rb, symbol, callback) {
    var result = function(wsc, browseData) {
        wsc.off('browse', result);
        wsc.off('failed', result);

        var err = null;
        if (wsc.errno < 0) {
            err = new Error("Browsing symbol " + symbol + " failed!");
            err.status = wsc.errno;
        } else {                
            saveBrowseData(rb, browseData);
        }
        callback(err, symbol);
    };
    // Register temporary listeners
    rb.wsc.on('browse', result);
    rb.wsc.on('failed', result);

    // Browse symbol
    rb.wsc.browse(symbol);
} 

RexBrowser.prototype.refresh = function() {
    var that = this;
    var browseRequestNumber = 1;

    var browseResult = function(err, symbol) {
        browseRequestNumber--;
        var item = that.getSymbol(symbol);

        _.each(item.children, function(child) {
            if (child.browse) {
                browseRequestNumber++;
                debug("Browsing: " + child.cstring);
                browse(that,child.cstring, browseResult);
            }
        });

        if (browseRequestNumber === 0) {
            that.emit('refresh', that);
        }
    };

    // Start recursive browsing
    browse(this,'$', browseResult);
};-
Ondřej Severa
  • 359
  • 5
  • 12
  • 1
    Well, you are using the same handler for all your events (`result`) and from this point on your handler uses the same callback for all events. So this is what you programmed as far as I can see. – Edwin Dalorzo Jun 02 '14 at 13:26
  • Yeh, I can see it now also. I thought that when I call `var result` it will create new function every time I call `browse` function. So I will have several different handler. I found out that first emit of the event will deregister all listeners using `wsc.off` function. S I will have to introduce some tags for each call to recognize from which response are `browseData` comming from. – Ondřej Severa Jun 02 '14 at 13:39
  • How does it matter that you create a new function if it does the same thing? – Edwin Dalorzo Jun 02 '14 at 13:42
  • It should store the link to the `callback` function. When I browse some 'symbol' I want to be able to call callback function which belongs to the currently browsed 'symbol'. Basically whole code is part of the asynchronous recursive tree traversal. – Ondřej Severa Jun 02 '14 at 13:59

1 Answers1

1

You could try using a IIFE:

} else {
    function(rbInner, browseDataInner){
        saveBrowseData(rbInner, browseDataInner);
    }(rb, browseData);
}

This makes sure the variables used by / in saveBrowseData have the values they have when the function is called.

Cerbrus
  • 70,800
  • 18
  • 132
  • 147