Javascript 如何给承诺增加延迟?向节点http.request承诺添加延迟
试图给NodeJS中的每个http.request添加一个小延迟,但当然,node始终处于同步模式。所以问题是,一旦承诺兑现,我如何重新设定承诺的状态Javascript 如何给承诺增加延迟?向节点http.request承诺添加延迟,javascript,node.js,promise,async-await,settimeout,Javascript,Node.js,Promise,Async Await,Settimeout,试图给NodeJS中的每个http.request添加一个小延迟,但当然,node始终处于同步模式。所以问题是,一旦承诺兑现,我如何重新设定承诺的状态 当前,helper.delay()在开始时只工作一次,然后立即发送所有http请求,导致服务器出错 为什么我不能在我的module.exports中的其他承诺中使用this.delay()?但它在正常的可导出函数中运行良好 离题。如何根据请求的URL将http切换到https? (无需复制相同的代码,消除冗余) 尝试在承诺内设置默认超时,使用新的
const wait=require(“util”).promisify(设置超时);
module.exports={
延迟:异步功能(秒){
等待等待(秒*1000);
},
getUrl:函数(url){
返回新承诺((解决、拒绝)=>{
const options=新URL(URL);
const resolver=http.request(选项,res=>{
res.setEncoding(“utf8”);
让responseBody='';
res.on(“数据”,正文=>{
响应体+=主体
});
res.on('end',()=>resolve(responseBody));
});
解析程序.end();
});
}
};
应用程序
const helper=require(“./exports.js”);
异步函数getdata(url){
const data=wait help.getUrl(url);
让results=JSON.parse(数据);
结果=结果。答案;
返回结果;
}
函数获取数据(el,i){
获取数据(el)。然后(
answer=>{console.log(answer)},
//…等等
)
}
函数getLinksFromFile(文件){
helper.readFile(文件)
。然后(arr=>{
arr.forEach((el,i)=>{
/////////下发//////////////
helper.delay(4)。然后(()=>{
////它只等一次
返回数据(el,i);
});
});
});
}
getLinksFromFile(“./links.txt”);
目标尽可能简单,读取url表单文件,从url获取json数据,然后执行其他操作无依赖性为了更好地理解承诺,你需要更多地阅读承诺是如何工作的,或者做更多的承诺实验 那么这段代码的作用是什么:
arr.forEach((el, i) => {
/////////ISSUE HERE BELOW//////////////
helper.delay(4).then(() => {
////It only waits once
return fetchData(el, i);
});
});
您迭代arr
的每个元素,并使用helper.delay(4)
为每个元素创建延迟承诺。但所有这些承诺几乎都是在同一时间创建的(仅相隔几纳秒),因为forEach并不等待一个承诺链完成。因此,每个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)
}
}
异步函数getLinksFromFile(文件){
让arr=await helper.readFile(文件);
对于(i=0,i可能您可以使用类似队列的东西:或者更简单的方法在前一个请求完成后执行每个请求。因此,可以使用
arr=>{arr.forEach
而不是async(arr)=>{for(i=0;i
谢谢罗兰,我可以用软件包立即解决这个问题,但我对依赖关系有点过敏;)此外,在我的导出上,所有内容都是异步的,我发布的是一个迷你版,因此人们可以点击。我编写这些函数只是为了寻求帮助,因此更容易理解。仍然找不到带有处理程序和setTimeout的http.request的在线示例。如果不承诺,那么这么做很容易,我可能最终会使用一些request/got/superagent无故调用。感谢nodejsy您不能在常规函数中使用wait。getLinksFromFile
需要像这样异步async函数getLinksFromFile(file){
尝试了多次,当我将wait放在那里时,我的IDE会立即将其标记为红色。是的,所有内容都是异步的。使用此功能,除超时外,所有内容都可以正常工作。它在2秒内运行329个http调用,8次失败,其中6次是真正的失败,2次错过。无论如何,在之前和之后从未在设置超时上花费过这么多时间仍然没有结果。也许我应该承诺全部或找出如何使delay()可更新。@jsdaily抱歉忘记了async
关键字,如果你想使用wait
@jsdailyPromise,你总是需要添加这一点。在不破坏承诺链的情况下,所有的都是正确的承诺方式(在你的情况下会发生这种情况),但它仍然会导致与forEach
方法相同的问题。原因是您将已创建的承诺列表传递给Promise.all
。也尝试了异步,只等待一次。但我还没有尝试循环,这可能会起作用。问题是,这是我拥有的一个巨大函数,所有内容都嵌套在该函数中les,我只是为了在这里发布它而将其拆分。奇怪的是,承诺仍然履行,并且不再尝试fetchdata可以正常工作的地方,但这是因为url每次都不同,这让我相信是时间。所以我尝试了两次延迟,顺序使用不同的参数,一次是4,一次是3。如果它们都是4,则仅此而已工作过一次。太奇怪了。谢谢你!