[英]Node.js file blocks terminal after correct execution
我是使用 Node 和 fetch 的新手,当然我的代码有一些问题。 本质上,我正在尝试实施一个项目,通过 API 请求获取一些 json 数据并将其存储到 mysql 数据库中。 这些数据包含在多个页面中,因此我使用了一个简单的 for 循环进行多次获取。 我这样做了 2 次,因为我必须从 2 个不同的 object 列表中获取数据。 为了存储数据,我首先建立了一个 mysql 连接,然后我在另一个内部执行 sql 查询以迭代单个 object 数据。 它正确执行 json 数据的提取和 mysql 数据库中的存储,但是一旦我在终端上执行node index.js
,该进程将继续运行并且终端暂停,直到我强制该进程终止。 我使用了为什么节点运行并发现了这一点:
下面是 index.js 的代码:
import mysql from 'mysql';
import fetch from 'node-fetch';
import log from 'why-is-node-running';
const URL0 = "https://atlas.ripe.net/api/v2/probes/?status=1";
const sql = "INSERT INTO probes (id, country, longitude, latitude) VALUES (?,?,?,?)";
const sql1 = "INSERT INTO anchors (id, country, longitude, latitude) VALUES (?,?,?,?)";
const PG_SIZE = 100;
let num_pages_probes=120;
let i=0, j=1, k=1, a=0;
const con = mysql.createConnection({
host:'localhost',
user:'root',
password:'',
database:'probes&anchors'
});
con.connect((err)=>{
if(err){
console.log("Connection not proper");
}else{
console.log("connected");
}
});
/*
fetch(URL0)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP error! status: "
+ response.status);
} else {
return response.json();
}
})
.then((data) => {
num_pages_probes = Math.ceil(data.count/PG_SIZE);
console.log(num_pages_probes);
});
*/
for (j; j<=2; j++){
console.log("j="+j);
let URLi = "https://atlas.ripe.net/api/v2/probes/?page="+j+"&status=1";
fetch(URLi)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP error! status: "
+ response.status);
} else {
return response.json();
}
})
.then((data) => {
for (let probe of data.results){
i++;
let id0 = probe.id;
let country = probe.country_code;
let longitude = probe.geometry.coordinates[0];
let latitude = probe.geometry.coordinates[1];
con.query(sql, [id0, country, longitude, latitude], function (err, result) {
if (err) throw err;
console.log("1 record inserted");
});
console.log("id0: "+id0+"\t"+"cc: "+country+"\t"+"long: "+longitude+"\t"+"lati: "+latitude);
console.log(i);
}
// con.end();
});
}
for (k; k<=2; k++){
console.log("k="+k);
let URLi = "https://atlas.ripe.net/api/v2/anchors/?page="+k;
fetch(URLi)
.then((response) => {
if (!response.ok) {
throw new Error("HTTP error! status: "
+ response.status);
} else {
return response.json();
}
})
.then((data) => {
for (let anchor of data.results){
a++;
let id0 = anchor.id;
let country = anchor.country;
let longitude = anchor.geometry.coordinates[0];
let latitude = anchor.geometry.coordinates[1];
con.query(sql1, [id0, country, longitude, latitude], function (err, result) {
if (err) throw err;
console.log("1 record inserted");
});
console.log("id0: "+id0+"\t"+"cc: "+country+"\t"+"long: "+longitude+"\t"+"lati: "+latitude);
console.log(a);
}
});
}
setTimeout(function () {
log() // logs out active handles that are keeping node running
}, 100)
有人可以帮帮我吗? 我不知道把手放在哪里。
PS。 我故意将周期限制为 2,但实际上应该是 120。
你没有关闭你的 mysql 连接,这会让你的进程保持正常。
您可能希望在所有获取/插入完成后关闭连接,这里的技巧是确保您在关闭连接之前完成所有插入。
您可以查看 async/await 语法,它将帮助您确保仅在完成插入后才关闭。
一个非常简化的版本如下所示:
const fn = async () => {
const con = mysql.createConnection({ ... });
for (...) {
const res = await fetch({ ... });
const data = await res.json();
await con.query({ ... });
}
await con.close();
}
fn();
注意: mysql
库似乎只适用于回调,因此您可能必须承诺您需要的方法(请参阅 utils.promisify)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.