1

流星纤维“同步”模式让我发疯。这是一个简单的代码示例:

var feedsData = feeds.fetch(); // [{_id: "1234"}, {_id: "6789", url: "http://...."}]
for(var i = 0, len = feedsData.length; i < len; i++) {
    var feed = feedsData[i];
    parser.parseURL(feed.url, function(err, out){
        console.log(feed._id, i); // outputs "6789" and "2" each times
    });
}

我不明白如何使这项工作。循环结束后调用回调,但应保留内部内部变量(例如 feed)……而它们不是。

解析的 url 很好(第一个,然后是第二个),但是我无法更新我的数据,因为我在回调中没有好的 _id。

想要的输出将是:“1234”“0”和“6789”“1”,而不是“6789”“2”两次......你如何在 Meteor / Fiber 代码中做到这一点?

4

4 回答 4

1

另一种在“纤维”中做到这一点的方法(它可能比我上面发布的“未来”的答案更好):

var feedsData = feeds.fetch(); // [{_id: "1234"}, {_id: "6789", url: "http://...."}]
Fiber(function() {
    var fiber = Fiber.current;
    for(var i = 0, len = feedsData.length; i < len; i++) {
        var feed = feedsData[i];
        parser.parseURL(feed.url, function(err, out) {
            console.log(feed._id, i);
            if(err) return fiber.throwInto(err);
            fiber.run();
        });
        Fiber.yield();
        console.log('here', i);
    }
    console.log('there');
}).run();
console.log('and there');

输出将是:

"and there"
"1234" "0"
"here" "0"
"6789" "1"
"here" "1"
"there"

请注意,Fiber 函数中的所有内容都在其自己的 Fiber 中执行,就好像它是异步的一样,这就是为什么首先输出“and there”的原因

于 2013-03-26T21:26:56.040 回答
0

好的,这是这样做的“纤维”方式:

var Future = require('fibers/future'),
wait = Future.wait,
feedsData = feeds.fetch(); // [{_id: "1234"}, {_id: "6789", url: "http://...."}],
parseUrl = Future.wrap(parser.parseURL);
Fiber(function() {
    for(var i = 0, len = feedsData.length; i < len; i++) {
        var feed = feedsData[i];
        var out = parseUrl(feed.url).wait();
        console.log('here', i, out);
    }
    console.log('there');
}).run();
console.log('and there');

结果输出将是:

"and there"
"here" "0" "the out data from the 1st callback"
"here" "1" "the out data from the 2nd callback"
"there"

正是你所期望的。Fibers 中的“未来”期望给函数的最后一个参数是回调,并将返回 err 作为第一个参数

于 2013-03-26T21:14:12.860 回答
0

最简单的解决方案是:

feeds.fetch().forEach(function(feed,i) {
    parser.parseURL(feed.url, function(err, out){
        console.log(feed._id, i);
    });
});

Javascript 没有块作用域(但是,letES6 中出现了),只有函数作用域。

于 2013-07-16T09:40:15.283 回答
0

不确定这与 Meteor、Fibers 或“同步模式”有什么关系。我认为这只是您的javascript中的一个错误。您正在循环遍历数组,然后在回调中调用对象的属性。当然,当最终调用回调时,它会查看 的当前值feed,这将是循环退出后最近分配的值。

因此,您应该重写代码以考虑到这一点:

var feedsData = [{_id: "1234"}, {_id: "6789", url: "http://...."}]
for(var i = 0, len = feedsData.length; i < len; i++) {
    var feed = feedsData[i];
    parser.parseURL(feed.url, function(err, out){
        console.log(this._id, arguments[0]); // will output "1234 0" and "6789 1"
    }.bind(feed, i));
}
于 2013-03-26T20:28:15.517 回答