队列的JS Foreach Alternative(超时)



我正在处理"全部批准";按钮这里的过程是当我点击";全部批准,";每个个体";批准";按钮将被触发为";点击";然后它将向控制器发送POST请求。然而,当我单击Approve All按钮时,出现了一个竞争条件,导致控制器返回Error 500: Internal server error。我曾尝试使用值为1500*iter的JSsetTimeout(),但当迭代器变得更高时,例如在i = 100,则需要1500*100 => 150000ms (150s)。我希望这能清楚地解释问题。有没有办法防止这种情况发生?

这是我的代码,我正在使用JQuery:

let inspection = $this.parents("li").find("ul button.approve"); // this will get all 'approve' button to be clicked at once
inspection.each((i,e)=>{ 
(function () {
setTimeout(function () { 
$(e).data("note",r);
$(e).click();
}, 1500 * i); // this acts like a queue, but when i > 100, it takes even longer to send POST requests.
})(this,i,e,r);
});
// then, each iteration will send a POST request to the controller.
$("#data-inspection ul button.approve").on("click", function() {
// send POST requests
});

任何帮助都将不胜感激。非常感谢。

500错误也可能是由于无法同时处理所有请求而导致服务器崩溃。

我建议使用事件驱动的方法,而不是setTimeout。你的1500米基本上是一个猜测——你不知道点击是否会发生得太快,或者你是否会让用户不必要地等待。

我将在没有jQuery的情况下演示如何做到这一点,并将jQuery的实现留给您:

// use a .js- class to target buttons your buttons directly,
// simplifying your selectors, and making them DOM agnostic
const buttonEls = document.querySelectorAll('.js-my-button'); 
const buttonsContainer = document.querySelector('.js-buttons-container');
const startRequestsEvent = new CustomEvent('customrequestsuccess');
// convert the DOMCollection to an array when passing it in
const handleRequestSuccess = dispatchNextClickFactory([...buttonEls]);
buttonsContainer.addEventListener('click', handleButtonClick);
buttonsContainer.addEventListener(
'customrequestsuccess',
handleRequestSuccess
);
// start the requests by dispatching the event buttonsContainer
// is listening for
buttonsContainer.dispatchEvent(startRequestsEvent);
// This function is a closure:
//   - it accepts an argument
//   - it returns a new function (the actual event listener)
//   - the returned function has access to the variables defined
//     in its outer scope
// Note that we don't care what elements are passed in - all we
// know is that we have a list of elements
function dispatchNextClickFactory(elements) {
let pendingElements = [...elements];
function dispatchNextClick() {
// get the first element that hasn't been clicked
const element = pendingElements.find(Boolean);
if (element) {
const clickEvent = new MouseEvent('click', {bubbles: true});
// dispatch a click on the element
element.dispatchEvent(clickEvent);
// remove the element from the pending elements
pendingElements = pendingElements.filter((_, i) => i > 0);
}
}
return dispatchNextClick;
}
// use event delegation to mitigate adding n number of listeners to 
// n number of buttons - attach to a common parent
function handleButtonClick(event => {
const {target} = event
if (target.classList.contains('js-my-button')) {
fetch(myUrl)
.then(() => {
// dispatch event to DOM indicating request is complete when the
// request succeeds
const completeEvent = new CustomEvent('customrequestsuccess');

target.dispatchEvent(completeEvent);
})
}
})

这里可以进行许多改进,但这里的主要想法是:

  • 应该避免幻数-我们不知道处理请求的速度有多慢
  • 请求是异步的——我们可以明确地确定它们何时成功或失败
  • DOM事件功能强大
    • 处理DOM事件时,我们会对该事件执行一些操作
    • 当一些事件发生时,我们想让其他人知道,我们可以调度自定义事件。对于我们调度的每个事件,我们可以将任意多的处理程序附加到任意多的元素上——这只是一个事件,任何元素都可以对该事件执行任何操作。例如,如果我们想的话,我们可以通过为特定事件的每个元素附加一个监听器来使DOM中的每个元素都闪烁

注意:此代码未经测试

最新更新