Javascript Meteor(光纤)环路和回调

Javascript Meteor(光纤)环路和回调,javascript,meteor,node-fibers,Javascript,Meteor,Node Fibers,流星光纤“同步”模式让我发疯。下面是一个简单的代码示例: 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){

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

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
    });
}
var feedsData=feeds.fetch();//[{u-id:“1234”},{u-id:“6789”,url:http://...."}]
对于(变量i=0,len=feedsData.length;i
我不知道该怎么做。在循环结束后调用回调,但是应该保留feed等内部变量。。。但事实并非如此

解析的url是好的(第一个,然后是第二个),但是我不能更新我的数据,因为我在回调中没有好的id

想要的输出将是:“1234”“0”和“6789”“1”,而不是两次都是“6789”“2”。。。
您如何在Meteor/Fiber代码中实现这一点?

不确定这是否与Meteor、光纤或“同步模式”有关。我认为这只是javascript中的一个bug。在数组中循环,然后在回调中调用对象的属性。当然,当回调最终被调用时,它将查看
提要的当前值,该值将是循环退出后最近分配的值

因此,您应该重新编写代码以将其考虑在内:

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));
}
var feedsData=[{{u-id:“1234”},{u-id:“6789”,url:http://...."}]
对于(变量i=0,len=feedsData.length;i
不确定这是否与流星、光纤或“同步模式”有关。我认为这只是javascript中的一个bug。在数组中循环,然后在回调中调用对象的属性。当然,当回调最终被调用时,它将查看
提要的当前值,该值将是循环退出后最近分配的值

因此,您应该重新编写代码以将其考虑在内:

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));
}
var feedsData=[{{u-id:“1234”},{u-id:“6789”,url:http://...."}]
对于(变量i=0,len=feedsData.length;i
好的,以下是“光纤”方式:

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');
正是你所期望的。 Fibers中的“future”期望函数的最后一个参数是回调,并将err作为第一个参数返回。Ok,下面是“fiber”的方法:

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');
正是你所期望的。
Fibers中的“future”期望给函数的最后一个参数是回调,并将返回err作为第一个参数,这是在“Fibers”中执行此操作的另一种方法(可能比我上面发布的“future”的答案更好):


请注意,Fiber函数中的所有内容都在其自身的光纤中执行,就好像它是异步的一样,这就是为什么“and there”首先在“Fiber”中输出的原因(这可能比我上面发布的“future”的答案要好):


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

最简单的解决方案是:

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

Javascript没有块作用域(然而,ES6中出现了
let
),只有函数作用域。

最简单的解决方案是:

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

Javascript没有块作用域(但是,ES6中会出现
let
),只有函数作用域。

很抱歉,这不起作用:TypeError:无法调用未定义的方法“bind”。feed变量是每个循环的内部变量,因此不应该重新分配它,在两个循环之后,每个回调都有两个独立的feed变量。我找到了问题的解决方案,我会在一分钟内发布更多错误,但它仍然会同时输出“6789”和“2”:-/刚刚发布了两个不同的答案,都是有效的,并且按照“预期”工作:)Javascript没有块作用域,只有函数作用域。每次迭代都会重新分配feed变量。Rahul的回答是正确的-这与光纤、节点或meteor无关,只是Javascript:)抱歉,但这不起作用:TypeError:无法调用未定义的方法“bind”。feed变量是每个循环的内部变量,因此不应该重新分配它,在两个循环之后,每个回调都有两个独立的feed变量。我找到了问题的解决方案,我会在一分钟内发布更多错误,但它仍然会同时输出“6789”和“2”:-/刚刚发布了两个不同的答案,都是有效的,并且按照“预期”工作:)Javascript没有块作用域,只有函数作用域。每次迭代都会重新分配feed变量。Rahul的回答是正确的——这与光纤、节点或流星无关,只是Javascript:)