gpt4 book ai didi

javascript - foreach在mysql插入之前执行操作

转载 作者:行者123 更新时间:2023-12-03 05:12:16 25 4
gpt4 key购买 nike

我仍然很难理解这些步骤是如何运行的。

基本上我正在做一个 foreach 计算颜色,然后用普通的 foreach 将其插入数据库中代码:

var mysql = require("mysql"),
namer = require('color-namer'),
async = require('async');
var connection = mysql.createConnection({
multipleStatements: true,
host : 'localhost',
user : 'root',
password : 'root',
database : 'xxxx'});
connection.connect();




connection.query(
`SELECT color from sg_fashion_colors limit 10`,
function(err, results, fields) {
results.forEach(function(elem){

var currentHex = elem['color'],
currentColor = namer(currentHex);
console.log(currentHex);
connection.query(
`INSERT INTO name_color_pat_test (hex, basic) VALUES (?,?);`,
[currentHex,currentColor['basic'][0]['name']] ,
function(err,data){
console.log("insert");
}
);
});
}
);

但不是这样做

color 
insert
color
insert

确实如此

color
color
insert
insert

我只是不明白为什么它首先对颜色进行 foreach,然后对插入进行 foreach。

有关信息,我能够使用异步产生我想要的预期输出

connection.query(
`SELECT color from sg_fashion_colors limit 10`,
function(err, results, fields) {
async.eachSeries(results, function (elem, seriesCallback) {
var currentHex = elem['color'],
currentColor = namer(currentHex);
console.log(currentHex);
connection.query( `INSERT INTO name_color_pat_test (hex, basic) VALUES (?,?);`, // insert the SKU inside a database with their primary color
[currentHex,currentColor['basic'][0]['name']] ,
function(err, results, fields) {
if (err) throw err;
console.log("insert");
seriesCallback(null);
});
}, function(responsetoendofloop){
console.log("everything has run");
});
}
);

最佳答案

让我在这里展示另一个简化的案例:

var colors = ['blue', 'red', 'green'];
colors.forEach(function(color) {
console.log('before setTimeout', color);
setTimeout(function () {
console.log('after setTimeout', color);
}, 0);
});

如果我在 Chrome 控制台中尝试,输出如下:

VM1119:3 before setTimeout blue
VM1119:3 before setTimeout red
VM1119:3 before setTimeout green
<- undefined
VM1119:5 after setTimeout blue
VM1119:5 after setTimeout red
VM1119:5 after setTimeout green

你的脚本中也发生了同样的事情。 setTimeout 与 connection.query 类似,因为它们都是异步调用回调,这意味着它们只有在当前堆栈执行完毕后才会调用回调函数。因此,在这两种情况下,forEach 都会继续循环,一旦完成,回调就会按照计划的顺序执行。请注意,当colors.forEach执行完成时,会打印undefined,它代表函数的返回值。尝试将其更改为 colors.map

让我再举一个例子:

setTimeout(function () { console.log('hello'); }, 0)
while (true) {};

如您所见,setTimeout 位于无限 while 循环之前,它应该立即执行(0 毫秒后),但它永远不会执行。当 javascript VM 读取第一行时,它将安排稍后调用回调,然后它将读取第二行,并且会卡在那里。在堆栈中的其他所有内容执行完毕之前,setTimeout 回调永远不会被调用。

现在 connection.query 也会发生同样的事情。它的回调计划稍后调用。调用也可能需要十几毫秒或更长时间(取决于网络和数据库)。因此,当它被调用时,其他所有内容都已经执行完毕。

现在,async.eachSeries 不会像 forEach 那样进行迭代。它会一直等到回调被调用,无论需要多长时间。

因此,如果您在 connection.query 回调之外调用回调,那么可能会得到与 forEach 相同的结果(这是错误的代码,不要更改您的代码,仅用于您的教育):

    async.eachSeries(results, function (elem, seriesCallback) {
var currentHex = elem['color'],
currentColor = namer(currentHex);
console.log(currentHex);
connection.query( `INSERT INTO name_color_pat_test (hex, basic) VALUES (?,?);`, // insert the SKU inside a database with their primary color
[currentHex,currentColor['basic'][0]['name']] ,
function(err, results, fields) {
if (err) throw err;
console.log("insert");

});

seriesCallback(null);
});

发生这种情况是因为现在 connection.query 结果之前的 seriesCallback 已准备就绪,即使它放置在其之后。

如果仍然不清楚,请随时在评论中提出更多问题。

关于javascript - foreach在mysql插入之前执行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41755810/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com