前文介紹過前后端防重復提交的基本場景,簡單的情況是只發起一個異步請求,如果有多個異步請求怎么操作呢?這個要分情況看下。
如果是后端服務器的接口支持一次傳遞多個申請,那么可以將任務放進數組中,發往后端。這是最好的方式,如果后端現在還不支持,最好說服改進下。
如果就是不支持的話,那么在前端做成并發異步任務,等待所有任務解禁再次提交按鈕。
如果批量任務是發給不同的后端服務器處理,那么也是要在前端做成并發異步任務處理的。
這種情況下,使用Promise.allSettled是最好的方式了。
function exectask(target){return new Promise((resolve,reject)=>{axios.post(url,{"target":target}).then(res => { if (res.data.code!="200") reject(res.data.code)else resolve()}).catch(errp => reject(errp)) });
}Promise.allSettled(tasklist.map(item => exectask(item))).then((ret)=>{//console.log(ret) $("#tasksubmit").attr("disabled",false);if (document.getElementById("taskul").getElementsByTagName("li").length==0) $("#taskseldiv").css("display","none"); });
如果后端任務執行時間短,那么可以這樣用,時間長的話,就不好這么用異步調用后.then里等結果出來執行后面的操作,而是直接執行,不用.then操作,不過要用定時器來定時查詢后端處理狀態。可以參考前面的文章《后臺耗時任務的前后端協同方法》
如果后端限制單用戶并發連接數的話或者就是想在前端限一下并發任務數的話,可以參考以下代碼:
(async () => {let ret = [];let executing = [];let tasksum=dealpool.length;for (let i=0;i<tasksum;i++) {let p = Promise.resolve().then(() => excetask(dealpool[i]));ret.push(p);if ( poolLimit<= tasksum) {let e = p.then(() => executing.splice(executing.indexOf(e), 1));executing.push(e);if (executing.length >= poolLimit) { await Promise.race(executing); }}}await Promise.allSettled(ret).then((res)=>{ //console.log(res) $("#tasksubmit").attr("disabled",false);if (document.getElementById("taskul").getElementsByTagName("li").length==0) $("#taskseldiv").css("display","none"); });})();