javascript - Variable not updating properly -
this relevant code :
this sends request server, takes username argument.
function send_client_lookup(username) { send( auth.aocp.client_lookup, [ [ 's', username.tostring() ] ] ) }
this part handles response server.
handle[auth.aocp.client_lookup] = function (data, u) { console.log('client_lookup') var userid = u.i() var username = u.s() u.done() console.log({ userid : userid, username : username }) // works var idresult = userid; // can use userid assigned idresult make code easier understand. }
the above 2 functions work how supposed to, nothing change/fix there.
now have function receives request 1 user , sends request user, takes 2 arguments: first arg userid of user sends request , second username of user request sent server/game works userids username has converted:
var commands = { invite: function(userid, username) { send_client_lookup(username); // send request server find out userid of username send_privgrp_invite(idresult); } }
the problem idresult == undefined, unless call cmd.invite() again idresult == 'with previous response this:
cmd.invite(user1); cmd.invite(user2); cmd.invite(user3);
and output of idresult is:
idresult == undefined idresult == 'info user1' idresult == 'info user2'
i tried defining idresult outside response handler , update inside, make sure not sort of delay server did massive invite spam , result same, 1 step behind no matter how fast sent invites. suggestions welcome :)
the problem rather hard solve, sending , collecting replies isolated. seems send()
sends packet , handle()
receives reply, , there can many possible unrelated packets between sending , receiving.
if it's case special global map should created link requests , responses. cases when there 2 concurrent requests same username, eventemitter
events
module fit, it's multimap of strings callbacks:
var events = require('events') var outstandinglookups = new events.eventemitter()
so when send lookup register 1 time listener, there's no need manual cleanup:
var commands = { invite: function(username) { outstandinglookups.once(username, function (idresult) { send_privgrp_invite(idresult); }) // send request server find out userid of username send_client_lookup(username); } }
in response handler emit
conveniently calls callbacks expecting userid
received username
:
handle[auth.aocp.client_lookup] = function (data, u) { console.log('client_lookup') var userid = u.i() var username = u.s() u.done() console.log({ userid : userid, username : username }) // works // can use userid assigned idresult // make code easier understand. var idresult = userid; // addition original handler code outstandinglookups.emit(username, idresult) }
the need use outstandinglookups.once
implementation detail , should encapsulated/hidden if want lookup userids in more 1 place in code.
i use promises q
npm library remember interface, similar es6 promises should used in production code modern standard.
var q = require('q') var commands = { lookupusername: function (username) { var result = q.defer() outstandinglookups.once(username, function (idresult) { result.resolve(idresult); }) // send request server find out userid of username send_client_lookup(username); return result.promise }, invite: function(username) { commands.lookupusername(username).then(function (idresult) { send_privgrp_invite(idresult); }) } }
the code commands.invite
cleaner now.
Comments
Post a Comment