我的代码是为了在每分钟写入约束为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 await(这对我来说是新的)但它似乎并没有改变行为。
谢谢!
根据要求,显示我如何尝试使用此代码的promises:
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测试中同时进行所有调用。
另外值得注意的是,我在请求调用的回调中有一个决心。它解决了,所以即使我的应用程序的下一部分一直完成到最后。这就是为什么我在这里没有拒绝或决心。
如何在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
,但它需要处理错误。可以进行更多重构。
我认为,这里最重要的改进是我们没有提前提出要求。这样我们就可以保留控制权,并且需要改变或者任何事情都会变得混乱,我们可以突破循环而不会再将垃圾邮件发送给服务器。
最好的选择是使用返回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);
);
}
}