簡體   English   中英

如何使用不同的參數多次運行一個函數,但等到所有函數都完成后再使用 promise 繼續我的代碼邏輯?

[英]How can I run a function multiple times with a different parameter, but wait until all are finished to continue with my code logic using promises?

我將一個 CSV 文件上傳到服務器,然后在后端我將該文件拆分為多個較小的文件(因為這些文件可能會變得非常大)。 上傳和拆分文件后,我想處理文件以將一些新數據插入數據庫。

所有邏輯都正常工作,但是,在所有文件完成處理后,我需要運行一些清理代碼。 經過一段時間的研究,我發現我可以通過使用 Javascript 承諾來實現這一點。

我一直在理解 Javascript 承諾方面遇到問題,這是我連續第二個晚上熬夜到午夜試圖完成這項工作,所以我認為我對 Javascript 承諾的理解不會很快提高那么多,我只是需要完成這項工作。

任何在 Javascript 承諾方面有經驗的人,你能看到我做錯了什么或我錯過了什么嗎? 我下面的代碼非常具有解釋性(我認為)。

 function sendAjaxRequest(data, callback, addUploadEvents = false) { return new Promise(function (resolve, reject) { let xhr = new XMLHttpRequest(); xhr.open('POST', ajaxurl); // when finished, we run our passed callback xhr.onload = callback; // only when uploading the file if ( addUploadEvents ) { xhr.addEventListener('loadstart', function() { console.log('uploading file'); }); xhr.addEventListener('progress', function(evt) { console.log('loaded: ' + evt.loaded + ', total: ' + evt.total); }); xhr.addEventListener('loadend', function() { console.log('file uploaded'); }); } // general events to catch errors xhr.addEventListener('timeout', function(e) { console.log('the request has timed out', e); reject(e); }); xhr.addEventListener('error', function(e) { console.log('the request returned an error', e); reject(e); }); xhr.addEventListener('abort', function(e) { console.log('the request was aborted', e); reject(e); }); // send the request xhr.send(data); }); } function uploadFile() { let data = new FormData(), f = document.querySelector('form [name="csv"]').files; data.append('csv', f[0]); // send the request let req = sendAjaxRequest(data, function() { if ( this.status === 200 ) { const response = JSON.parse(this.response); if ( ! response.success ) { console.log('error in the uploadFile request'); return false; } // once the file is uploaded, we want to split it into several smaller pieces splitToMultipleFiles(); } else { // should not reach this ever, I think I covered all problematic cases console.log('there was an error in the request', this); } }, true); // returning false to prevent the form from reloading the page return false; } function splitToMultipleFiles() { let data = new FormData(); // send the request let req = sendAjaxRequest(data, function() { if ( this.status === 200 ) { const response = JSON.parse(this.response); if ( ! response.success ) { console.log('error in the splitToMultipleFiles request'); return; } // response.data.files has an array of files I want to process in the backend one at a time let processingFiles = response.data.files.map(function(file) { return processFile(file); }); // wait until all files have been processed, then run some cleanup logic // the problem is, the promises are never resolved :( Promise.all(processingFiles).then(function() { console.log('all done, cleanup your mess'); }); } }); } function processFile(tempFile) { let data = new FormData(); data.append('temp-file', tempFile); // send the request return sendAjaxRequest(data, function() { if ( this.status === 200 ) { const response = JSON.parse(this.response); if ( ! response.success ) { console.log('error in the processFile request for file ' + tempFile); return; } console.log('file finished processing: ' + tempFile); } }); }

好吧,我想我需要安排一門關於 Javascript 承諾的好課程作為明年的目標..現在,我能夠像這樣解決我的困境,可能不是最好的方法,但它確實有效:

 function sendAjaxRequest(data, callback, addUploadEvents = false) { let xhr = new XMLHttpRequest(); xhr.open('POST', ajaxurl); // when finished, we run our passed callback xhr.onload = callback; // only when uploading the file if ( addUploadEvents ) { xhr.addEventListener('loadstart', function() { console.log('uploading file'); }); xhr.addEventListener('progress', function(evt) { console.log('loaded: ' + evt.loaded + ', total: ' + evt.total); }); xhr.addEventListener('loadend', function() { console.log('file uploaded'); }); } // general events to catch errors xhr.addEventListener('timeout', function(e) { console.log('the request has timed out', e); }); xhr.addEventListener('error', function(e) { console.log('the request returned an error', e); }); xhr.addEventListener('abort', function(e) { console.log('the request was aborted', e); }); // send the request xhr.send(data); } function uploadFile() { let data = new FormData(), f = document.querySelector('form [name="csv"]').files; data.append('csv', f[0]); // send the request let promise = new Promise(function(resolve, reject) { sendAjaxRequest(data, function() { if ( this.status === 200 ) { const response = JSON.parse(this.response); if ( ! response.success ) { console.log('error in the uploadFile request'); return false; } resolve(response.data); } else { // should not reach this ever, I think I covered all problematic cases console.log('there was an error in the request', this); reject(this.status); } }, true); }); promise.then(splitToMultipleFiles, function(err) { console.log('promise rejected', err); }); // returning false to prevent the form from reloading the page return false; } function splitToMultipleFiles() { let data = new FormData(); // send the request let promise = new Promise(function(resolve, reject) { sendAjaxRequest(data, function() { if ( this.status === 200 ) { const response = JSON.parse(this.response); if ( ! response.success ) { console.log('error in the splitToMultipleFiles request'); return; } // response.data.files has an array of files I want to process in the backend one at a time resolve(response.data.files); } else { reject(this.status); } }); }); promise.then(function(files) { let processingFiles = files.map(function (file) { return processFile(file); }); // wait until all files have been processed, then run some cleanup logic Promise.all(processingFiles).then(function () { console.log('all done, cleanup your mess'); }); }, function(err) { console.log('promise rejected', err); }); } function processFile(tempFile) { let data = new FormData(); data.append('temp-file', tempFile); // send the request return new Promise(function(resolve, reject) { sendAjaxRequest(data, function() { if ( this.status === 200 ) { const response = JSON.parse(this.response); if ( ! response.success ) { console.log('error in the processFile request for file ' + tempFile); return; } console.log('file finished processing: ' + tempFile); resolve(response.data); } else { reject(this.status); } }); }); }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM