【问题标题】:Async call generates " Error: Can't wait without a "fiber", even with _wrapAsync异步调用会生成“错误:没有“光纤”就无法等待,即使使用 _wrapAsync
【发布时间】:2014-01-21 15:02:56
【问题描述】:

我在流星中使用 RSS 解析器时遇到了问题。这是一个异步调用,所以它不需要被包装,但它似乎仍然不起作用。我认为这是因为匿名 on('readable' 函数在光纤之外,但我看不到如何解决它。

var FeedParser = Meteor.require('feedparser');
var request = Meteor.require('request');

function getBlog(url, parameter, id){

    request(parameter)
        .on('error', function (error) {
            console.error(error);
        })
        .pipe(new FeedParser())
        .on('error', function (error) {
            console.error(error);
        })

        .on('readable', function () {
            var stream = this,
                item;
            while (item = stream.read()) {
                Items.insert(new_item);                
            }
        });
    }

var wrappedGetBlog = Meteor._wrapAsync(getBlog);


Meteor.methods({
    blog: function (url, parameter, id) {
        console.log('parsing blog');
        var items = wrappedGetBlog(url, parameter, id);
    }
});

【问题讨论】:

    标签: meteor event-loop


    【解决方案1】:

    Meteor._wrapAsync() 期望被包装的函数返回错误和结果给回调。您的函数 getBlog() 没有这样做,因此 _wrapAsync 不是正确的方法。

    我之前包装了that function,但使用了Future。

    这种方法允许我从 Meteor.method() 调用 feedparser,这不允许异步函数,但您也尝试在可读事件中执行 insert。我认为insert 如果不在光纤中会抱怨。也许这样也是必要的:

    var r = request( parameter );
    r.on( 'response' , function(){
    
      var fp = r.pipe( new FeedParser() );  //need feedparser object as variable to pass to bindEnvironment 
    
      fp.on('readable', Meteor.bindEnvironment( 
        function () {
          var stream = this,
            item;
          while (item = stream.read()) {         
            Items.insert(new_item);                
          }
        }
        , function( error ){ console.log( error );}
        , fp // variable applied as `this` inside call of first function 
      ));
    });
    

    纤维是另一种选择...

    var Fiber = Npm.require( "fibers" );
    
     .on('readable', function () {
        var stream = this,
            item;
        while (item = stream.read()) {         
            Fiber( function(){
              Items.insert(new_item);
              Fiber.yield();
            }).run();                
        }
    });
    

    【讨论】:

    • 感谢您查看此内容。问题是这样做会导致流变量失去它的上下文,因此它不再具有 stream.read() 方法。我发现 Feed Parser 的语法非常混乱......
    • 也可以使用光纤。将输出传递回方法并让它执行插入也可以。
    • 太棒了,完美运行。看来我可能得开始了解 Fibers 了。
    猜你喜欢
    • 2017-11-04
    • 2015-12-21
    • 2015-09-22
    • 2014-02-28
    • 1970-01-01
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    相关资源
    最近更新 更多