如何为Promise解决方案增加延迟?为节点http.request promise

时间:2019-08-09 13:07:54

标签: javascript node.js promise async-await settimeout

试图在NodeJS中为每个http.request添加一个小的延迟,但是当然node总是进入同步模式。那么问题来了,一旦兑现承诺,我该如何重置它的状态?

  1. 当前 helper.delay()在开始时只能运行一次,然后所有http请求都会立即发送,从而导致服务器出错。
  2. 为什么我不能在模块内部的其他承诺中使用 this.delay()?但它在正常的可导出函数中运行良好。
  3. 主题外。如何根据请求的URL将http切换为https? (无需复制相同的代码,从而消除了冗余)。

尝试在promise中使用默认设置超时,将http.request封装为新的setTimeoutpromise,并尝试使用外部“ requestHandler”作为回调,该函数以可nnable的形式运行。等 也许我必须 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数据并执行操作。 无依赖项

1 个答案:

答案 0 :(得分:1)

您需要多读一些有关诺言如何工作的信息,或对诺言进行更多的实验,以更好地理解它们。

那么这段代码是做什么的?

 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。