为每个循环节点内部使用请求模块 js 不会更新我的 JSON



这段代码可能出了什么问题?在forEach循环之后,我无法获得更新的json(变量更新DataJSON)输出,任何人都可以帮助我吗?提前感谢,这是我的代码,我在这里错过了什么吗?

app.get('/getDifferences', (req, res) => {
let changed = false,
updatedJSON = { data: [] },
updatedDataJSON = { "url": "", "dta": "", "status": "unchanged" };
fs.readFile('output.json', 'utf-8', (err, data) => {
storedData = data && JSON.parse(data);
if (storedData) {
storedData.data.forEach((e) => {
request.get(e.url).on('res', (html) => {
updatedDataJSON.url = e.url;
updatedDataJSON.dta = e.dta;
if (e.dta && (e.dta.match(/<body[^>]*>[sS]*</body>/gi)[0] !== html.match(/<body[^>]*>[sS]*</body>/gi)[0])) {
changed = true;
updatedDataJSON.status = "changed";
updatedDataJSON.dta = html;
}
updatedJSON.data.push(updatedDataJSON);
});
});
console.log(updatedDataJSON);
}
});
res.end(JSON.stringify(updatedJSON))
});

Node js 是异步的。因此,您必须在forEach循环中结束get请求的回调中的响应,当get请求将调用存储Data.data长度时间时。

在这里,我附上代码来演示这一点。

app.get('/getDifferences', (req, res) => {
let changed = false,
updatedJSON = { data: [] },
updatedDataJSON = { "url": "", "dta": "", "status": "unchanged" };
fs.readFile('output.json', 'utf-8', (err, data) => {
var count = 0,
arraylength;
storedData = data && JSON.parse(data);
if (storedData) {
arraylength = storedData.data;
storedData.data.forEach((e) => {
request.get(e.url).on('res', (html) => {
updatedDataJSON.url = e.url;
updatedDataJSON.dta = e.dta;
if (e.dta && (e.dta.match(/<body[^>]*>[sS]*</body>/gi)[0] !== html.match(/<body[^>]*>[sS]*</body>/gi)[0])) {
changed = true;
updatedDataJSON.status = "changed";
updatedDataJSON.dta = html;
}
updatedJSON.data.push(updatedDataJSON);
count++;
if (count === arraylength) {
console.log(updatedDataJSON);
res.end(JSON.stringify(updatedJSON));
}
});
});
}
});
});

问题

他代码的执行顺序与编写它的顺序不同。这称为异步。这意味着request.get被解雇,然后解决。

你希望这个。

  1. 读取文件。
  2. 完成第一项。
  3. 请求第一项的数据(它被触发)
  4. 接收第一项的数据(它解析)
  5. 完成第二项。
  6. 请求第二项的数据(它被触发)
  7. 接收第二项的数据。(它解决)

正在发生的事情更像是这样的:

  1. 读取文件。
  2. 完成第一项。
  3. 请求第一项的数据(它被触发)
  4. 完成第二项。
  5. 接收第一项的数据(它解析)
  6. 请求第二项的数据(它被触发)

看看顺序有何不同?代码先转到第二项,然后再从第一项接收数据。这是因为您正在向网络服务器询问一些数据。同时,您的代码继续运行,然后网络服务器说"嘿,这是您要求的数据"。

想象一下,摆好桌子,你把叉子放在桌子上,让我把刀拿来。放一把叉子,等我带一把刀。你再放一把叉子,等我拿刀等等。

你向我要刀,同时把所有的叉子都放在桌子上,不要等我。当我拿着刀来时,你把它们放在桌子上。

解决方案1)签出异步/等待: https://tutorialzine.com/2017/07/javascript-async-await-explained

2)减少承诺:https://gist.github.com/anvk/5602ec398e4fdc521e2bf9940fd90f84

除了https://www.youtube.com/watch?v=8aGhZQkoFbQ

节点.js 是异步的,它在读取文件之前返回响应。 尝试异步模块或承诺处理异步操作。

最新更新