首页 文章

Meteor wrapasync保存对Mongo集合的Twitter REST响应,给出错误“错误:Meteor代码必须始终在光纤内运行” .

提问于
浏览
0

我正在尝试使用Twitter REST API GET关注者/ ids并使用Mongo集合插入方法将其保存到Mongo

/server/server.js中的代码:

Meteor.startup(function () {
    // code to run on server at startup

    TwitterFollowersIDsCollecions = new Mongo.Collection("twitterFollowersIDs");

    var Twit = Meteor.npmRequire('twit');
    var T = new Twit({
        consumer_key:         '###',
        consumer_secret:      '###',
        access_token:         '###',
        access_token_secret:  '###'
    });

    var getTwitterFollowersIDsAsync = function (screenname, cb) {
        T.get('followers/ids', { screen_name: screenname }, function (err, data, response) {
                console.log(data);
                var vids = data.ids;
                for(var i in vids) {
                    TwitterFollowersIDsCollecions.insert({
                        twitterFollowerID:vids[i]
                    });
                }
            }
        );
    };

    Meteor.methods({
        getTwitterFollowersIDsCollectionsClient : function (screenname){
            var getTwitterFollowersIDsNow = Meteor.wrapAsync(getTwitterFollowersIDsAsync);
            var result = getTwitterFollowersIDsNow('meteorjs');
            console.log(result);
            return result;
        }
    });

});

服务器控制台错误:

Error: Meteor code must always run within a Fiber. 
Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.

目标是将Twitter粉丝保存到Mongo集合中 .

流星v.1.1.0.2

流星套餐:

  • 流星平台

  • autopublish

  • 不安全

  • 差异:硫化

  • accounts-twitter

  • accounts-ui

  • meteorhacks:npm

  • npm-container

在流星内部使用的npm模块通过 meteorhacks:npm"twit": "1.1.20" (在packages.json中添加)

更新第二次尝试

Meteor.startup(function () {

  // code to run on server at startup

  TwitterFollowersIDsCollecions = new Mongo.Collection("twitterFollowersIDs");

  var Twit = Meteor.npmRequire('twit');

  var T = new Twit({
        consumer_key:         '###',
        consumer_secret:      '###',
        access_token:         '###',
        access_token_secret:  '###'
    });

  Meteor.methods({

    // this is the server method called from the client

    getTwitterFollowersIDsCollectionsClient : function (){
      setTimeout(function(){
        Meteor.call('getTwitterFollowersIDsNow', 'meteorjs');
      },10);
      return;
    },

    getTwitterFollowersIDsNow : function (screenname) {
      T.get('followers/ids', { screen_name: screenname }, function (err, data, response) {
        console.log(data);
      });
    }

  });

});

然后我从浏览器控制台调用以下代码:

Meteor.call('getTwitterFollowersIDsCollectionsClient');

服务器崩溃时出现相同的错误:

Error: Meteor code must always run within a Fiber. Try wrapping callbacks     that you pass to non-Meteor libraries with Meteor.bindEnvironment.

UDPATE:

getTwitterFollowersIDsCollectionsClient : function (screenname){
  Meteor.setTimeout(function(screenname){
    T.get('followers/ids', { screen_name: screenname }, Meteor.bindEnvironment(function (err, data, response) {
    console.log("from getTwitterFollowersIDsCollectionsClient : "+data.ids);

    var vids = data.ids;
    for(var i in vids)
      {
        TwitterFollowersIDsCollecions.insert({
          twitterFollowerID:vids[i]
        });
      }

    return data;
  }));

  },10);
  return;
}

将Meteor.bindEnvironment添加到T.get回调方法 . 此代码有效,我能够将关注者ID保存到mongo集合中

3 回答

  • 0

    很高兴你得到它的工作,但我玩这个和Meteor提供另一个,超级简单的方法:wrapAsync . 至少,一旦我弄清楚它就很容易了!这是我用的服务器代码 -

    var T = new TwitMaker({
        consumer_key:         '...'
      , consumer_secret:      '...'
      , access_token:         '...'
      , access_token_secret:  '...'
    })
    
    var wrapGet = Meteor.wrapAsync(T.get, T);
    
    Meteor.methods({
    
      getTwitImg: function(target) {
        data = wrapGet('users/show', {screen_name: target});
        if (data) {
          img_url = data['profile_image_url'];
          US.update({twitter: target}, {$set: {'targetImg': img_url}});
          return img_url;
        }
      }
    
    });
    

    对于客户端和模板代码,请参阅此要点:https://gist.github.com/DanAncona/a09ce375e48bfa8efeca

  • 2

    你的代码有点令人困惑 . 您似乎正在尝试执行Web服务调用异步,但仍然立即返回结果(这将无效) .

    首先,您可能不需要包装该函数来获取异步块中的关注者 .

    如果您希望服务器方法在调用后立即向客户端返回某些内容,我将使用 Meteor.setTimeout (请参阅What's the point of Meteor.setTimeout() vs just setTimeout()?)块并调用另一种方法来执行获取:

    Meteor.methods({
    
        // this is the server method called from the client
        getTwitterFollowersIDsCollectionsClient : function (screenname){
            Meteor.setTimeout(function() { 
              Meteor.call('getTwitterFollowersIDsNow', 'meteorjs');
            }, 10);
            return;
        },
    
        getTwitterFollowersIDsNow : function (screenname) {
            T.get('followers/ids', { screen_name: screenname }, function (err, data, response) {
                console.log(data);
                var vids = data.ids;
                for(var i in vids) {
                    TwitterFollowersIDsCollecions.insert({
                        twitterFollowerID:vids[i]
                    });
                }
            }
        }
    });
    

    理想情况下,您将使用模板助手从您的集合中检索您的关注者 . 由于这些助手是被动的,你可以从客户端调用服务器方法,让Meteor的反应性解决你通过帮助器返回追随者的问题(在数据更改时重新执行/重新渲染模板) ) .

  • 0

    试着打电话:

    var wrappedInsert = Meteor.bindEnvironment(function(tweet) {
    TweetsCollection.insert(tweet);},
    "Failed to insert tweet into Posts collection.");
    

    来自api回调内部

    getTwitterFollowersIDsNow : function (screenname) {
      T.get('followers/ids', { screen_name: screenname }, function (err, data, response) {
        for(var i in data)
        {
         wrappedInsert(data[i]);
        }     
      });
    }
    

相关问题