我的代码,以便在每分钟60个写限制的在线服务中创建多个展示位置:
placementsToAdd.forEach((placement, index) => {
setTimeout(() => {
options.url = `https://api.company.com/placement?publisher_id=${existingPub ? existingPub : placementsJson[0].PublisherId}&site_id=${placement.siteId}`
options.body = `{"placement":{"name":"${placement.placement}"}}`
request(options, callback);
},1000 * (index + 1))
})
这种方式可以工作,但是如果一次有2000或3000个展示位置列表,我会担心等待时间,等待时间可能会过长。
是否有更好的方法来重构此代码,以使我的请求每秒建立一次,无论如何?如果没有该“ *(索引+ 1)”,它似乎会继续尝试在60岁以后立即将所有建筑物都撞墙。
我尝试使用promises和async等待(这对我来说是新的),但是它似乎并没有改变行为。
谢谢!
根据要求,显示如何通过以下代码使用promise:
async function createThePlacements() {
let promise = new Promise((resolve, reject) => {
for (let i = 0; i < placementsToAdd.length; i++) {
setTimeout(() => {
options.url = `https://api.company.com/placement?publisher_id=${existingPub ? existingPub : placementsJson[0].PublisherId}&site_id=${placementsToAdd[i].siteId}`
options.body = `{"placement":{"name":"${placementsToAdd[i].placement}"}}`
request(options, callback);
},1000)
}
});
let result = await promise; // pause till the promise resolves
console.log('result - ', result);
}
createThePlacements();
因此,免责声明-如前所述,我从没使用过Async Await,所以请仔细阅读以了解其工作原理。这似乎是语法,但目前我的结果似乎什么都没有,但是代码也继续执行应做的工作,只是试图一次一次完成300次测试中的所有调用。>
另外,值得注意的是,我在请求调用的回调内部有一个解决方法。它可以解决,因此即使我的应用程序的下一部分也一直完成到最后。这就是为什么我在这里没有拒绝或解决的原因。
答案 0 :(得分:3)
如何在forEach循环中每秒运行一次setTimeout?
最直接的方法是:
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
for (const placement of placementsToAdd) {
const options = {...};
request(options, callback);
await wait(1000);
}
await
可以在普通for循环内运行,而不是forEach
内运行。
我没有碰过您的callback
,但它需要处理错误。可能有更多的重构。
我认为,这里最重要的改进是我们不会提前推送请求。通过这种方式,我们可以保留控制权,并且在需要进行更改或发生任何麻烦时,我们可以摆脱循环,而不会在几分钟内向服务器发送垃圾邮件。
答案 1 :(得分:1)
最好的选择是拥有一个返回Promise的request
方法。
然后您可以像这样重写代码。
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
function requestPlacement(placement) {
const options = {...};
return request(options);
}
async function requestAllPlacements(placements) {
for(let i = 0; i < placements.length; i+=60) {
if (i > 0) {
// wait 1 minute
await(sleep(60000));
}
await Promise.all(
placements
.slice(i, 60)
.map(requestPlacement);
);
}
}