尝试为 NodeJS 中的每个 http.request 添加一点延迟,但当然 Node 始终处于同步模式。所以问题是一旦 promise 被履行,我如何重置它的状态?
- 目前 helper.delay() 在开始时仅工作一次,然后所有 http 请求都会立即发送,导致服务器出错。
- 为什么我无法在 module.exports内部的其他 Promise 上使用this.delay()?但它在普通的可导出函数中工作得很好。
- 偏离主题。如何根据请求的 URL 将 http 切换为 https? (无需复制相同代码,消除冗余)。
尝试了 Promise 中的默认设置超时,用新的 setTimeout Promise 包装了 http.request,尝试使用外部“requestHandler”作为回调,该回调将函数作为 thennable 运行。等等等等 也许我必须clearTimeout? https://nodejs.org/api/timers.html
导出
const wait = require("util").promisify(setTimeout);
module.exports = {
delay: async function(seconds){
await wait(seconds * 1000);
},
getUrl: function(url){
return new Promise((resolve, reject) => {
const options = new URL(url);
const resolver = http.request(options, res => {
res.setEncoding("utf8");
let responseBody = '';
res.on("data", body => {
responseBody += body
});
res.on('end', () => resolve(responseBody));
});
resolver.end();
});
}
};
应用程序
const helper = require("./exports.js");
async function getdata(url) {
const data = await help.getUrl(url);
let results = JSON.parse(data);
results = results.answer;
return results;
}
function fetchData(el, i) {
getdata(el).then(
answer => { console.log(answer)},
//...etc
)
}
function getLinksFromFile(file) {
helper.readFile(file)
.then(arr => {
arr.forEach((el, i) => {
/////////ISSUE HERE BELOW//////////////
helper.delay(4).then(() => {
////It only waits once
return fetchData(el, i);
});
});
});
}
getLinksFromFile("./links.txt");
目标很简单,读取 url 表单文件,从 url 获取 json 数据并执行一些操作。 无依赖
最佳答案
您需要更多地阅读有关 Promise 如何工作的内容,或者对 Promise 进行更多实验,以更好地理解它们。
那么这段代码的作用是:
arr.forEach((el, i) => {
/////////ISSUE HERE BELOW//////////////
helper.delay(4).then(() => {
////It only waits once
return fetchData(el, i);
});
});
您迭代 arr 的每个元素,并使用 helper.delay(4)
为每个元素创建一个用于延迟的 Promise。但所有这些 Promise 都是大致在同一时间创建的(仅相隔几纳秒),因为 forEach 不会等待一个 Promise 链完成。因此,每个 fetchData
都会比 forEach
发生的时间延迟 4 秒。
解决该问题的最简单方法是将代码转换为使用 await
/async
语法:
async function getLinksFromFile(file) {
let arr = await helper.readFile(file);
for( let i=0, i<arr.length ; i++) {
let el = arr[i];
await helper.delay(4)
await fetchData(el, i)
}
}
在常规循环中使用 await
会在该点暂停循环,直到 Promise 得到解决。
关于javascript - 如何为 Promise 解析添加延迟?为 Node http.request Promise 添加延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57430734/