Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Functions not synchronous #34

Open
muuvmuuv opened this issue Nov 4, 2016 · 5 comments
Open

Functions not synchronous #34

muuvmuuv opened this issue Nov 4, 2016 · 5 comments

Comments

@muuvmuuv
Copy link

muuvmuuv commented Nov 4, 2016

Hey I#m currectly working on an MEAN-Stack project and using node-teamspeak for pulling some information about specific clients. The problem is I cant return a valid result, because the function are asyncronous.

Maybe some one knows a better solution or add this functionality to the repo.

Here the code:

function CompareTeamspeakClients(forumUsers) {
  var deferred = Q.defer();
  var cl = new TeamSpeakClient("127.0.0.1");
  

  cl.send("login", {client_login_name: "serveradmin", client_login_password: "M+h8YzUA"}, function(err, response, rawResponse){
    if (err) deferred.reject(err);

    cl.send("use", {port: 9987}, function(err, response, rawResponse){
      if (err) deferred.reject(err);

      forumUsers.forEach(function(user, index){
        cl.send("clientdbfind", ["uid"], {pattern: user.tsid}, function(err, response, rawResponse){
          if (err) {
            deferred.reject(err);
          } else {
            cl.send("clientdbinfo", {cldbid: response.cldbid}, function(err, response, rawResponse){
              if (err) deferred.reject(err);
              
              forumUsers[index]['tsdbid'] = response.client_database_id;
              forumUsers[index]['tsnickname'] = response.client_nickname;
              forumUsers[index]['tslastconnected'] = response.client_lastconnected;
            });
          }
        });
      });
    });
  });
  
  deferred.resolve(forumUsers);

  return deferred.promise;
}

Thanks

@muuvmuuv muuvmuuv changed the title Functions no synchronous Functions not synchronous Nov 4, 2016
@starwolfy
Copy link

Your function is returning a value while at the same time it is still executing the TeamSpeak queries.

function CompareTeamspeakClients(forumUsers) {
  var deferred = Q.defer();
  var cl = new TeamSpeakClient("127.0.0.1");


  cl.send("login", {client_login_name: "serveradmin", client_login_password: "M+h8YzUA"}, function(err, response, rawResponse){
    if (err) deferred.reject(err);

    cl.send("use", {port: 9987}, function(err, response, rawResponse){
      if (err) deferred.reject(err);

      forumUsers.forEach(function(user, index){
        cl.send("clientdbfind", ["uid"], {pattern: user.tsid}, function(err, response, rawResponse){
          if (err) {
            deferred.reject(err);
          } else {
            cl.send("clientdbinfo", {cldbid: response.cldbid}, function(err, response, rawResponse){
              if (err) deferred.reject(err);

              forumUsers[index]['tsdbid'] = response.client_database_id;
              forumUsers[index]['tsnickname'] = response.client_nickname;
              forumUsers[index]['tslastconnected'] = response.client_lastconnected;

              // I have no clue what deffered.resolve does but I'm assuming it has to be moved here too.
              deferred.resolve(forumUsers);
              return deferred.promise;

            });
          }
        });
      });
    });
  });
}

@muuvmuuv
Copy link
Author

muuvmuuv commented Nov 4, 2016

@nikitavondel but this will return the result many times (depending of the database). Can I not just use is syncronous?

// foreach..
var response = cl.send("clientdbfind", ["uid"], {pattern: user.tsid});
// other code...
// endforeach
console.log(response);

@starwolfy
Copy link

@muuvmuuv Sorry I did not see you were performing a foreach loop, as far as I am concerned you cannot execute this synchronously unless you really want to rewrite the code. I recommend keeping track of when you are in the last foreach loop and then returning a large object or array which has the results of all loops stored. (I am just brainstorming with you here, it might not make perfect sense in your scenario)

@iglosiggio
Copy link

You can promisify the send function to make your life easier, then you can resolve to a promise generated from Promise.all

Example (i'm using v8 native promises, arrow functions and varargs):

function CompareTeamspeakClients(forumUsers) {
    const cl = new TeamSpeakClient("127.0.0.1");
    /* Promisified send */
    function send(...args) {
        return new Promise((accept, reject) =>
            cl.send(...args,  (err, response) => {
                if(err) reject(err);
                else accept(response);
            }));
    }
    return send("login", {client_login_name: "serveradmin", client_login_password: "M+h8YzUA"})
        .then(() => send("use", {port: 9987}))
        .then(() => Promise.all(forumUsers.map((user) =>
            send("clientdbfind", ["uid"], {pattern: user.tsid})
                .then((response) => ({
                    tsdbid: response.client_database_id,
                    tsnickname: response.client_nickname,
                    tslastconnected: response.client_lastconnected
                })
            )
        );
}

@antoine-pous
Copy link

You can use my client which is more advanced and implement promises.

https://github.com/antoine-pous/node-teamspeak3-client

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants