最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Make Meteor method synchronous - Stack Overflow

programmeradmin3浏览0评论

I've been attempting to make this function synchronous. I've read several Stack Overflow posts about Async but I'm unable to comprehend how I would be able to make this synchronous. As of now, it is asynchronous therefore it returns undefined before heading into the callback function.

I call it from the client side:

Meteor.call('screenName',function(error,result) {
        if (error) {
          console.log(error);
        }
        else {
          window.alert(result);
        }
      }

And this is the server side method:

Meteor.methods({
  'screenName': function() {
      T.get('search/tweets',
      {
        q:'#UCLA',
        count:1
      },
      function(err,data,response) {
        var temp = data.statuses[0].user.screen_name;
        console.log(temp);
        return temp;
      }
    )
  }
});

I'm using the Twitter API and what I want to do is basically retrieve the screen name from the JSON and return it to a variable on the client side. But this is returning undefined because the callback is being compiled after the compiler has reached the end of the 'screenName' function.

I want it to return the value from the callback function but reading up other examples has not helped me comprehend how I can transform my code. I need to make this function synchronous but I don't know how to do it.

I've been attempting to make this function synchronous. I've read several Stack Overflow posts about Async but I'm unable to comprehend how I would be able to make this synchronous. As of now, it is asynchronous therefore it returns undefined before heading into the callback function.

I call it from the client side:

Meteor.call('screenName',function(error,result) {
        if (error) {
          console.log(error);
        }
        else {
          window.alert(result);
        }
      }

And this is the server side method:

Meteor.methods({
  'screenName': function() {
      T.get('search/tweets',
      {
        q:'#UCLA',
        count:1
      },
      function(err,data,response) {
        var temp = data.statuses[0].user.screen_name;
        console.log(temp);
        return temp;
      }
    )
  }
});

I'm using the Twitter API and what I want to do is basically retrieve the screen name from the JSON and return it to a variable on the client side. But this is returning undefined because the callback is being compiled after the compiler has reached the end of the 'screenName' function.

I want it to return the value from the callback function but reading up other examples has not helped me comprehend how I can transform my code. I need to make this function synchronous but I don't know how to do it.

Share Improve this question edited Jul 29, 2015 at 7:50 halapgos1 asked Jul 28, 2015 at 19:24 halapgos1halapgos1 1,1954 gold badges16 silver badges36 bronze badges 4
  • Because the twitter package I'm using is Node module and Node runs asynchronously so async helps it run synchronously...here's the link:github.com/meteorhacks/meteor-async Maybe I just understood it wrong. Feel free to correct me. – halapgos1 Commented Jul 28, 2015 at 19:47
  • ... Wait, have you reposted stackoverflow.com/questions/31664423/…? – Kyll Commented Jul 28, 2015 at 20:02
  • Oh shoot, I didn't realize I asked the same thing. Sorry. Um, how do I close the question? So I don't get banned or something lol.. – halapgos1 Commented Jul 28, 2015 at 20:07
  • Errr... I think the best thing is to flag as duplicate. But now you have two identical working solutions, one from me and one from @DavidWeldon. – Kyll Commented Jul 28, 2015 at 20:08
Add a comment  | 

5 Answers 5

Reset to default 9

Simply use Meteor.wrapAsync to turn your asynchronous T.get into a synchronously styled one!

It won't actually get executed in a pure "synchronous" way though, it is using a trick known as a Fiber, but you should read the docs to learn more.
Here goes:

var Tget = Meteor.wrapAsync(T.get);

Meteor.methods({
  'screenName': function() {
    return Tget({
      q : '#UCLA',
      count : 1
    }).status[0].user.screen_name;
  }
});

Browser-to-server, it is not possible to call methods synchronously. You're stuck with callback-style code. Synchronous calls are only possible on the server.

http://docs.meteor.com/#/basic/Meteor-call

On the client

Methods called on the client run asynchronously, so you need to pass a callback in order to observe the result of the call. The callback will be called with two arguments, error and result. The error argument will be null unless an exception was thrown. When an exception is thrown, the error argument is a Meteor.Error instance and the result argument is undefined.

On the server

On the server, you don't have to pass a callback — the method call will simply block until the method is complete, returning a result or throwing an exception, just as if you called the function directly.

However, synchronous style code for the server depends if everything else is synchronous. You might want to read the APIs docs if it is possible to write the Twitter API call synchronously. Otherwise, you'll be writing asynchronous code in the end.

I use the Promisse, is a great response with async/await.

Example:

// On Client

Template.nameTemplate.onCreated(async function(){
    const callFunctionTest = await getScoreByCountry({ name: 'Testando' });
    console.log(callFunctionTest);

});


async function getScoreByCountry(filter) {
    return await new Promise((resolve, reject) => {
        Meteor.call('app-method-test', filter , (error, resp) => {
            if(error) {
                reject(error)
            } else {
                resolve(resp)
            }
          })
    })
}


// On server

Meteor.methods({
    'app-method-test': test 
});

function test(filter = {}) {
    return App.Collections.NameCollection.findOne(filter)
}

@thatgibbyguy answer is the only one that worked for me. I also tried following libraries (maybe they will be useful for somebody):

meteor add simple:reactive-method
meteor add mnmtanish:call

This isn't synchronous code, but what I've done to send a server method's result back to a client side function is used serversession to do this. For example:

Meteor.methods({
  'screenName': function() {
      T.get('search/tweets',
      {
        q:'#UCLA',
        count:1
      },
      function(err,data,response) {
        var temp = data.statuses[0].user.screen_name;
        ServerSession.set('screenname',temp)
        return temp;
      }
    )
  }
});

You can now set a reactiveVariable, or a session, or a template helper to be:

ServerSession.get('screenname')
发布评论

评论列表(0)

  1. 暂无评论