Передача параметра через стороннюю функцию с обратным вызовом - PullRequest
0 голосов
/ 09 июня 2018

Я пытаюсь сделать что-то вроде следующего примера на основе mastering-javascript-callbacks-bind-apply-call .У меня есть класс, который управляет обратным вызовом, он срабатывает, и я хочу снова вызвать некоторый код внутри класса.В этом примере я связываю дополнительную переменную с классом this при определении обратного вызова, чтобы при вызове вызывать функции из класса.Все это прекрасно работает.

    #!/usr/bin/env node

class Doge {
    constructor(callback) {
        // bind an extra variable to the callback that represent the class instance 'this' context
        let boundCallback = callback.bind({doge: this});

        // associate the callback with the class
        this.callback = boundCallback;
    }

    // a way to initiate the callback (would normally be triggered with getting data for instance)
    doCallback(data) {
        this.callback(data);    
    }

    // something inside the class we want to get
    getSaying() {
        return "Such callback!";    
    }
}

//callback normally only gets one variable (i.e. the incoming data), but we've been sneaky and associated some data
// in the this context ...which was the this from the class instance
function callback(data) {
    console.log(data);
    console.log(this.doge.getSaying()); 
}

// creates class instance andsets the callback function (which is not in the class)
var doge = new Doge(callback); 

// call the callback with some data
doge.doCallback("test");

Я думал, что это будет имитировать функцию третьей стороны, инициирующую обратный вызов как средство передачи знания экземпляра класса обратному вызову (так как эта функция, вызывающая обратный вызов, изменяет«это»), но я ошибся или допустил ошибку.

В моем реальном примере используется библиотека веб-сокетов (ws).Я попытался реализовать аналогичную концепцию, и она жалуется, потому что «stream_this», который я связал с socketCallback, пропал.

const WebSocket = require('ws');

module.exports = class Stream {

    constructor(socket_url) {
        //we want to store data unique to the class instance here
        this.stream_data = {}
        this.ws = new WebSocket(socket_url);

        let boundCallback = socketCallback.bind({stream_this: this});
        this.callback = boundCallback;

        this.ws.on('message', boundCallback); // <--- callback association
    }

    addChannels(channels) {
        var self = this;

        this.ws.on('open', function open() {    
            self.ws.send(JSON.stringify(channels, null, 4));
        });           
    }

}

function socketCallback(data) {
    var self = this;
    var response = JSON.parse(data);  // turn the string back to JSON

    // primative response processor
    response.forEach(function(result) {

        if (result.channel == "addChannel") {
            // confirm the channel is subscribed too     
        } else {
            // associate data with the class instance somehow
            this.stream_this.stream_data[result.timestamp] = result.data  <- this.stream is undefined.
        }

    });
}

Как я могу передать знания обратному вызову экземпляра класса, чтобы я мог получить доступ к переменными функции экземпляра класса изнутри обратного вызова?Я знаю, что мог бы сделать это, удалив класс и имея глобальную переменную для данных, которые я хотел сохранить, но тогда код не будет повторно использоваться для нескольких экземпляров потока, которыми я мог бы управлять параллельно.

1 Ответ

0 голосов
/ 09 июня 2018

Нашел ответ на проблему, используя тот же метод.SocketCallback должен был быть внутри класса.Когда-то

this.stream_this

работает и может получить доступ к экземпляру класса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...