Ho una classe in questo modo:Come posso controllare il flusso del programma usando eventi e promesse?
import net from 'net';
import {EventEmitter} from 'events';
import Promise from 'bluebird';
class MyClass extends EventEmitter {
constructor(host = 'localhost', port = 10011) {
super(EventEmitter);
this.host = host;
this.port = port;
this.socket = null;
this.connect();
}
connect() {
this.socket = net.connect(this.port, this.host);
this.socket.on('connect', this.handle.bind(this));
}
handle(data) {
this.socket.on('data', data => {
});
}
send(data) {
this.socket.write(data);
}
}
Come dovrei girare il metodo send
in una promessa, che restituisce un valore dall'evento del socket data
? Il server invia dati solo quando i dati vengono inviati ad esso, a parte un messaggio di connessione che può essere facilmente soppresso.
Ho provato qualcosa di simile:
handle(data) {
this.socket.on('data', data => {
return this.socket.resolve(data);
});
this.socket.on('error', this.socket.reject.bind(this));
}
send(data) {
return new Promise((resolve, reject) => {
this.socket.resolve = resolve;
this.socket.reject = reject;
this.socket.write(data);
});
}
Ovviamente questo non funzionerà perché resolve
/reject
sovrascriverà l'altro quando concatenamento e/o chiamando send
più volte in parallelo.
C'è anche il problema di chiamare lo send
due volte in parallelo e risolve prima la risposta.
Attualmente ho un'implementazione che utilizza una coda e un file defers, ma ci si sente in disordine poiché la coda viene costantemente controllata.
mi piacerebbe essere in grado di effettuare le seguenti operazioni:
let c = new MyClass('localhost', 10011);
c.send('foo').then(response => {
return c.send('bar', response.param);
//`response` should be the data returned from `this.socket.on('data')`.
}).then(response => {
console.log(response);
}).catch(error => console.log(error));
Giusto per aggiungere, non ho alcun controllo sui dati che si riceve, il che significa che non può essere modificato al di fuori di il flusso.
Modifica: Quindi sembra che questo sia piuttosto impossibile, a causa del fatto che TCP non ha un flusso di richiesta-risposta. Come può essere implementato usando ancora promesse, ma usando una catena di promesse a esecuzione singola (una richiesta alla volta) o una coda.
Vuoi dire come una chat a due vie? Invia un messaggio e aspetta di ricevere un messaggio, in questo modo? – thefourtheye
@thefourtheye Quasi, tranne che potrebbe essere necessario chiamare 'send' in parallelo e la promessa dovrebbe restituire la risposta corretta a seconda di ciò che è stato inviato. Sebbene tutti i dati ricevuti provengano da un flusso, quindi non è esattamente tracciabile. –
Sto indovinando qui ... potresti impostare una specie di oggetto observer in 'socket' con un metodo' .add() ', quindi chiamare' this.socket.observer.add ({ \t \t \t rifiuto: rifiutare, \t \t \t determinazione: risolvere \t \t}; 'da' send() ' –