2017-07-30 80 views
0

我正在编写一个脚本,用于从第三方服务请求库存物品,然后它必须根据特定条件对其进行过滤。虽然Filter模块发回正确的响应,但调用Filter的方法无法将通过测试的项添加到数组中。NodeJS在回调之前等待

更具体地说,Inventory.loadClean()从第三方API获取数据,然后它调用Inventory.filter负责循环这些项目并检查它们是否通过标准。如果这些项目不会将它添加到数组中。

方法调用

// This is how Intentory.filter is called. All the parameters are correct. 
Inventory.filter(inv, rules, function(filtered) { 
    console.log(filtered); 
    next(filtered); 
}); 

Inventory.filter

filter: function (inv, rules, cb) { 
    var filtered_items = []; 
    for(var i = 0; i < inv.length; i++) { 
     Filter.itemPasses(inv[i], rules, function(passes, stage) { 
      //console.log(passes, stage); 
      if(passes) { 
       filtered_items.push(inv[i]); 
      } 
      if(i + 1 == inv.length) { 
       console.log("i+1:", i+1, "inv:", inv.length); 
       cb(filtered_items); 
      } 
     }); 
    } 
} 

这是相当直截了当。 Filter.itemPasses评估项目,并在回调中根据项目是否通过检查,值passes是真或假。

如果计算表达式i + 1 == inv.length声明这里找到:Underscore _.each callback when finished?

和想法是,你调用回调时处理的最后一个元素。虽然它看起来很合乎逻辑,但它并不适用。我仍然得到一个空阵列。

请注意,我检查了我的Filter中的所有方法,它们正在评估正确。以防万一你想看到filter.js这里是一个链接:https://gist.github.com/meletisf/d32a241ba2cbb168527f4342eabdf2a6

我敢肯定,它必须是异步的问题,但我不知道它是否导致。

+0

'Filter.meetsPriceLimits'调用了'Cache.get()'。难道这个函数会异步回答吗?带有'resp'参数的回调可能会引起怀疑。 – ccprog

+0

是的。 'Cache.get()'我是一个Redis的异步包装器。我知道这是造成问题,但我虽然通过使用多个回调脚本将工作如期。无论如何,请查看我的答案,关于我如何修复它。 – Meletis

回答

0

这可能是一个种族问题。这可能是回调更好的条件,也封我:

filter: function (inv, rules, cb) { 
var filtered_items = []; 
var count=0; 
for(let i = 0; i < inv.length; i++) {//the let is important 
    Filter.itemPasses(inv[i], rules, function(passes, stage) { 
     //console.log(passes, stage); 
     if(passes) { 
      filtered_items.push(inv[i]); 
     } 
     count++; 
     if(count == inv.length) {//the improved condition 
      console.log("i+1:", i+1, "inv:", inv.length); 
      cb(filtered_items); 
     } 
    }); 
    } 
} 
+0

有趣。现在它返回一个包含18个未定义元素的数组。 18是通过测试的项目数量。 – Meletis

+0

@Meletis您需要使用let ... –

0

试图检查每个变量是如何表现我偶然发现了以下结论后。

来自for循环的变量iInventory.filter方法内表现得很奇怪。更具体地说,它总是31.不知道为什么发生这种情况,但我很清楚,我应该从inv[i]获得当前项目。相反,如果它通过了所有条件,则更改Filter.itemPasses以返回项目对象。我还添加了Jonas建议的代码。我不知道它为什么可以工作,但它的工作原理。没有它,数组总是空的。

不幸的是,我不知道确切的答案,为什么代码是如此搞砸了,但通过实施我下面提到的修复我得到它的工作。

+0

您正在循环外的函数范围内定义'var i'。由于回调是异步调用的,在调用它时,循环已经完成,并且“i”已达到其最终值。 – ccprog

+1

看看循环内的闭包 - 简单实用的例子*在这里SO –