javascript - 如何为 Promise 解析添加延迟?为 Node http.request Promise 添加延迟

标签 javascript node.js promise async-await settimeout

尝试为 NodeJS 中的每个 http.request 添加一点延迟,但当然 Node 始终处于同步模式。所以问题是一旦 promise 被履行,我如何重置它的状态?

  1. 目前 helper.delay() 在开始时仅工作一次,然后所有 http 请求都会立即发送,导致服务器出错。
  2. 为什么我无法在 module.exports内部的其他 Promise 上使用this.delay()?但它在普通的可导出函数中工作得很好。
  3. 偏离主题。如何根据请求的 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/

相关文章:

javascript - 如何使用子上下文可访问的自定义属性扩展模板绑定(bind)语法?

javascript - 在 Grunt 任务中读取文件名

php倒计时服务器端

javascript - 如何使用reduce按json分组?

node.js - console.timeLog() 在 Jest 测试中不起作用

javascript - 使用 ng-translate 翻译不存在的键

node.js - 在 Mongoose Schema 中使用多个值的唯一文档

javascript - Node JS bluebird promise

typescript - 将 es6-promise 与 TypeScript 2.1 ES5 Webpack(异步/等待)一起使用

javascript - 链接多个可选异步 Ajax 请求