Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database NodeJS使用knex迭代太快_Database_Node.js_Asynchronous - Fatal编程技术网

Database NodeJS使用knex迭代太快

Database NodeJS使用knex迭代太快,database,node.js,asynchronous,Database,Node.js,Asynchronous,我在使用带有查询的for循环(knexjs.org)时遇到了一些困难。让我们开始如何遍历数组。我的数组如下所示: [ { module_id: 9, able: '1', will: '1' }, { module_id: 9, able: '1', will: '1' }, { module_id: 2, able: '1', will: '1' }, { module_id: 2, able: '1', will: '1' }, { module_id: 4, able: '1', will

我在使用带有查询的for循环(knexjs.org)时遇到了一些困难。让我们开始如何遍历数组。我的数组如下所示:

[ { module_id: 9, able: '1', will: '1' },
{ module_id: 9, able: '1', will: '1' },
{ module_id: 2, able: '1', will: '1' },
{ module_id: 2, able: '1', will: '1' },
{ module_id: 4, able: '1', will: '1' },
{ module_id: 4, able: '1', will: '1' },
{ module_id: 1, able: '1', will: '1' },
{ module_id: 1, able: '1', will: '1' },
{ module_id: 8, able: '1', will: '1' },
{ module_id: 8, able: '1', will: '1' },
{ module_id: 7, able: '1', will: '1' },
{ module_id: 7, able: '1', will: '1' },
{ module_id: 5, able: '1', will: '1' },
{ module_id: 5, able: '1', will: '1' },
{ module_id: 3, able: '1', will: '1' },
{ module_id: 3, able: '1', will: '1' },
{ module_id: 6, able: '1', will: '1' },
{ module_id: 6, able: '1', will: '1' } ]
然后是“有趣”部分:

for(var i = 0; i < obj.length; i++) {
        var object = obj[i];
        console.log("has object", object);
        db.knex('interests').where({
            inventory_id: inventory_id,
            module_id: object.module_id
        }).select().limit(1).then(function (result) {
            console.log("MODULE ID", object.module_id);
            if (result.length == 0) {

                db.knex('interests').insert({
                    inventory_id: inventory_id,
                    module_id: object.module_id,
                    could: object.able,
                    would: object.will
                }).then(function (a) {
                });
            } else {
                db.knex('interests').where({
                    inventory_id: inventory_id,
                    module_id: object.module_id
                }).update({
                    could: object.able,
                    would: object.will
                }).then(function (a) {
                });
            }
        });
    }
for(变量i=0;i
代码的作用如下:

  • 遍历数组
  • 查询数据库
  • 如果没有结果,创建一些东西
  • 如果有结果,更新一些东西
只有一个问题。for循环太快。或者,换句话说,查询太慢了。为什么?因为object.module_id始终是数组中的最后一个module_id


我如何确保它使用for循环中的module_id,而不是上次迭代时给它的变量?

实际上,不是节点太快。这是因为查询是异步工作的

流程不会等待查询完成以继续循环。当它们被执行时,循环已经结束

我建议将所有查询/更新包装在以数据为参数的函数中:链接回调方法,以便它们可以按预期工作

 var queryinterest =   function(object){
       db.knex('interests').where({
       inventory_id: inventory_id,
       module_id: object.module_id
    }).select().limit(1).then(function (result) {
        if (result.length == 0) {
                insertInterest(object)
        } else {
                updateInterest(object)             
    })
}
然后在主循环中调用它们

for(var i = 0; i < obj.length; i++) {
        queryInterests(obj[i])
        });
    }
for(变量i=0;i
编辑:这篇文章非常有助于阐明异步工作的原因和方法:


我将此方法用于类似的场景,您可能会发现它很有用。 比如说,在插入或更新记录之前,需要从堆栈中获取并解析下一个发票号,或者需要获取用户全名。 与其为每个select编写特定调用,不如使用通用函数:

async function select(table, args, single){
    //assumes you've already configured your knex object database details(hostname, password etc)
    return await knex.select().from(table).where(args).then(function(result) {
            //this formats the result into an easier to parse structure
            let returnObject = {};
            for (const [key, value] of Object.entries(result)) {

                returnObject[key] = value
            }
            //this will toggle whether you want all the rows returned or just the first, handy if you know theres only one match, but not strictly needed for this
            if (single == true) {
                return (returnObject[0])
            } else {
                return (returnObject);
            }
        }
    );
}
然后在主循环中:

(async function(){
        const result = await select('tableName',args,true);                        
        console.log(result);
})()

瞧!在将数据用于更新/插入之前,您已经准备好进行其他格式设置。您看到console.log的地方通常是我执行任何字符串操作、循环等操作的地方,只是为了让它在代码中更明显地分段。

我们就快到了,感谢您迄今为止的帮助。。。然而,在queryinterest中,“return q_result”返回未定义的结果,因为查询尚未完成。。。怎么解决?哎呀,我想我是打错了
q\u result
而不是
q\u result
,我编辑了我的代码!那也不行。在
q\u result=result