【问题标题】:Express.js - foreach array of data and store them in the databaseExpress.js - foreach 数据数组并将它们存储在数据库中
【发布时间】:2015-03-04 18:52:21
【问题描述】:

我正在使用 expressjs,bookshelf.js,我想发布数据数组,foreach 此类数据并保存。

我不确定问题出在哪里(快递、书架或只是普通的旧 javascript),但情况如下:当我发布所述数组并尝试遍历它时,我得到了正确数量的保存到数据库,但都具有数组中最后一项的值。

代码如下:

router.post('/save/', function(req, res){
    var data = req.body;
    var result = [];
    for (var i in data) {
        var d = data[i];
        if (d.user_id == -1) d.user_id = null;
        new Term().where({'date_of_driving': d.day})
        .fetch()
        .then(function(terms){
            if (terms != null) {
                return new Term({'id':terms.id}).save(d).then(function(item_updated){});
            } else {
                return new Term().save(d).then(function(item_saved){});               
           }
        })
        .catch(function(error){
            console.log(error);
        });
    }
    res.send({'saved': 'ok'});   
});

我的理解是,这些调用是异步的,并且总是对最后一个数据进行操作,因为 for 语句比 save 更快。我有什么事吗?

对于这个问题有哪些最好、最简单和最正确的解决方案?

【问题讨论】:

  • 这个question&answer 可能会帮助您了解您的问题。
  • 在这一行:return new Term({'id':term.id}).save(d).then(function(item_updated){}); term 未定义,d 没有引用您希望它引用的内容。如果 request.body 是一个数组,则使用标题建议的 foreach 可以解决该问题。
  • Kevin B 感谢您的回复:这是一个错字,我将代码翻译成英文,这在其中丢失了。我现在编辑了代码。我不完全理解您答案的第二部分 - 我正在使用 for 句子。据我所知,javascript中实际上没有“foreach”。或者有吗?

标签: javascript node.js promise bluebird bookshelf.js


【解决方案1】:

从您的代码中不清楚您是希望查询并行还是顺序运行。

我假设是并行的,但您可以将 .map 替换为 .each 并且它将按顺序运行

router.post('/save/', function(req, res){
    Promise.map(req.body, function(d) {
        if (d.user_id == -1) d.user_id = null;
        return new Term().where({'date_of_driving': d.day}).fetch().then(function(terms){
            if (terms != null) {
                return new Term({'id':terms.id}).save(d);
            } else {
                return new Term().save(d);    
            }
        });
    }).then(function() {
        res.send({'saved': 'ok'});
    }).catch(Promise.OperationalError, function(e) {
        // Note that stack reveals internal server code so you might
        // not want to send it over in production
        res.status(400).send({stack: e.stack, message: e.message});
    });
});

没有必要仅仅为了记录错误而捕获错误,因此我将其删除。仅在可以处理的情况下捕获错误。

【讨论】:

    【解决方案2】:

    本质上,“then”函数将异步执行,循环将继续独立执行,正如您所怀疑的那样。

    我相信一种解决方案是定义一个函数,该函数本质上将参数d 作为参考并以此执行异步内容。所以这应该有效:

    router.post('/save/', function(req, res){
        var data = req.body;
        var result = [];
        for (var i in data) {
            var d = data[i];
            if (d.user_id == -1) d.user_id = null;
            doTheThing(d);
        }
        res.send({'saved': 'ok'});   
    });
    
    
    function doTheThing(d) {
        new Term().where({'date_of_driving': d.day})
            .fetch()
            .then(function(terms){
                if (terms != null) {
                    return new Term({'id':terms.id}).save(d).then(function(item_updated){});
                } else {
                    return new Term().save(d).then(function(item_saved){});               
                }
            })
        .catch(function(error){
            console.log(error);
        });
    }
    

    【讨论】:

    • 使用Promise.map怎么样?他们想解决这类问题吗?
    • @uglycode 我是节点/promise 编程的初学者,所以我不知道答案(我也有兴趣了解优雅的解决方案)。我可能会研究一下(我一直打算完全学习 Bluebird 的 api),但同时我在您的帖子中添加了“bluebird”和“promise”作为标签(在同行评审之前不可见),所以让我们看看其他人是否可以插话。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-28
    • 2021-04-23
    • 1970-01-01
    • 2012-02-22
    相关资源
    最近更新 更多