2013-05-08 20 views
0

以下代码有什么问题?我收集了mongo中的水果,蔬菜和糖果。 “testlist”包含含有食物的字符串,这些食物属于三种类别之一,可以在藏品中查找。使用以下代码在nodejs + mongoose + async中执行同步时出现问题?

出于某种原因,转换后的列表从未出现由“糖果”组成,但仅包含水果和蔬菜。

var async = require("async"), 
    testlist = ["Tomato", "Carrot", "Orange", "Chocolate"]; 

async.map(testlist, function (food, next) { 
    async.parallel([function (done) { 
    Fruit.findOne({"name": food}, done); 
    }, 
    function (done) { 
    Vegetables.findOne({"name": food}, done); 
    }, 
    function (done) { 
    // The line below appears to execute successfully but never end up in "convertedList" 
    Candy.findOne({"name": food}, done); 
    } 
], function (err, foods) { 
     next(err, foods[0] || foods[1]); 
     }); 
    }, 
    function (err, result) { 

     var convertedList = [].concat(result); 
     res.send(convertedList); 
    }); 

为什么Candy没有被添加到生成的“convertedList”中?我该如何解决这个问题?

注意:我注意到,当我重新安排糖果和蔬菜的功能(完成)调用时,看起来蔬菜不会被添加到最终转换列表中,但是糖果会。它似乎总是被添加到convertedLIst中被忽略的第三个函数(done)。

回答

0

@JohhnyHK是正确的。除了怀疑您的查询返回的是非空值以外,没有其他解释为什么Candy从未出现在您的列表中。

该测试通过(使用摩卡):

var async = require('async'), 
    should = require('should'), 
    sinon = require('sinon'); 


describe('async map', function() { 
    var Fruit, Vegetables, Candy, service; 
    var noop = function() {}; 

    beforeEach(function() { 
    Fruit = sinon.stub({ findOne: noop }); 
    Vegetables = sinon.stub({ findOne: noop }); 
    Candy = sinon.stub({ findOne: noop }); 

    }); 


    it('should map', function (done) { 

    var testlist = ["Tomato", "Carrot", "Orange", "Chocolate"]; 

    // return null record for everything 
    Fruit.findOne.yields(null); 
    Vegetables.findOne.yields(null); 
    Candy.findOne.yields(null); 

    // return some value when query matches (simulating mongo queries basically) 
    Fruit.findOne.withArgs({name: 'Orange'}).yields(null, 'Orange'); 
    Vegetables.findOne.withArgs({name: 'Tomato'}).yields(null, 'Tomato'); 
    Vegetables.findOne.withArgs({name: 'Carrot'}).yields(null, 'Carrot'); 
    Candy.findOne.withArgs({name: 'Chocolate'}).yields(null, 'Chocolate'); 

    async.map(testlist, function (food, next) { 
     async.parallel([function (done) { 
     Fruit.findOne({ 
      "name": food 
     }, done); 
     }, 
      function (done) { 
     Vegetables.findOne({ 
      "name": food 
     }, done); 
     }, 
      function (done) { 
     // The line below appears to execute successfully but never end up in "convertedList" 
     Candy.findOne({ 
      "name": food 
     }, done); 
     } 
     ], function (err, foods) { 
     next(err, foods[0] || foods[1] || foods[2]); 
     }); 
    }, function (err, result) { 

     var convertedList = [].concat(result); 
     convertedList.should.eql(testlist); 
     done(); 
    }); 

    }); 
}); 
+0

不要忘记upvote,如果它帮助! :) – Mrchief 2014-09-09 04:33:35

0

这条线在你async.parallel回调不沿结果使从Candy查询:

next(err, foods[0] || foods[1]); 

试试这个:

next(err, foods[0] || foods[1] || foods[2]); 
+0

没有与修正路线,同样的问题开展工作。如果我重新命令下一个(err,食物[2] ||食物[0] ||食物[1]),那么只有Candy出现。其他人是空的。 – Rolando 2013-05-08 13:29:49