简体   繁体   English

Javascript:在执行下一个循环之前等待循环完成

[英]Javascript : wait for for loop to finish before executing next loop

I have a scenario where I have to delete attachments first and then upload new attachments.我有一个场景,我必须先删除附件,然后再上传新附件。 Here is my code:这是我的代码:

        var programs = this.UploadModel.getProperty("/programs/items"); 

        //Delete files first
        for(var i=0; i<filesToDelete.length; i++){
            oThis._callAttachmentWS("DELETE", proj, filesToDelete[i]);
        }

        //Then save new files   
        for(var i=0; i<programs.length; i++){
            oThis._callAttachmentWS("SAVE", proj, programs[i]);
        }

How do I make the second for loop wait for the first loop to finish?如何让第二个 for 循环等待第一个循环完成?

Since the OP within the comments states...由于评论中的 OP 指出......

"... it calls a web service and the return is true or false" “......它调用了 web 服务,返回是真还是假”

"... the function is coming from another controller. It can be changed. Since it's an ajax call, then callback back is most likely supported" “... function 来自另一个 controller。它可以更改。由于它是 ajax 调用,因此很可能支持回调”

... and looking at how... ......看看如何......

oThis._callAttachmentWS("DELETE", proj, filesToDelete[i]);

... respectively... ... 分别...

oThis._callAttachmentWS("SAVE", proj, programs[i]);

... are being used, one could assume the _callAttachmentWS method returns a Promise . ...正在使用,可以假设_callAttachmentWS方法返回Promise

Promise.all and Promise.allSettled are two methods each operating upon the states of a list of promises and returning a promise itself. Promise.allPromise.allSettled是两个方法,每个方法都对承诺列表的状态进行操作并返回 promise 本身。

The next provided example code utilizes the latter method.下一个提供的示例代码使用后一种方法。 The implementation also mocks the behavior of an asynchronous (promise returning) _callAttachmentWS method.该实现还模拟异步(承诺返回) _callAttachmentWS方法的行为。 There are promise returning helper functions for the also mocked file save/delete tasks.对于同样模拟的文件保存/删除任务,有 promise 个返回辅助函数。 The main task, called handleFileDeleteAndFileSave , shows a possible solution of how one could handle the promise chain(s)...称为handleFileDeleteAndFileSave的主要任务显示了如何处理 promise 链的可能解决方案...

 function callAttachmentWS(action, project, fileName) { return new Promise( (resolve, reject) => { setTimeout(() => { // file deletion completed. resolve({ action, fileName }); }, 3000); } ); } // var programs = this.UploadModel.getProperty("/programs/items"); // //Delete files first // for(var i=0; i<filesToDelete.length; i++){ // oThis._callAttachmentWS("DELETE", proj, filesToDelete[i]); // } // // //Then save new files // for(var i=0; i<programs.length; i++){ // oThis._callAttachmentWS("SAVE", proj, programs[i]); // } function triggerFileActions(action, fileList) { console.log(`+++ trigger ${ action.toLowerCase() } files +++`); // returns an array of promises. return fileList.map(fileName => /*oThis._*/callAttachmentWS(action, 'my-project-name', fileName) ) } function deleteFiles(fileList) { // returns a promise. return Promise.allSettled(triggerFileActions('DELETE', fileList)); } function saveFiles(fileList) { // returns a promise. return Promise.allSettled(triggerFileActions('SAVE', fileList)); } function handleFileDeleteAndFileSave(deleteList, saveList) { // returns a promise. return deleteFiles( deleteList ).then(deleteResultList => { deleteResultList.forEach(result => console.log(result)); console.log('... delete files finished...'); }).then(() => { // returns a promise. return saveFiles( saveList ).then(saveResultList => { saveResultList.forEach(result => console.log(result)); console.log('... save files finished...'); }).then(() => '+++ handleFileDeleteAndFileSave is settled +++'); }); } const filesToDelete = ['foo', 'bar', 'baz']; const programs = ['bizz', 'buzz']; handleFileDeleteAndFileSave( filesToDelete, programs, ).then(status => console.log(status));
 .as-console-wrapper { min-height: 100%;important: top; 0; }

As the above code shows, the properly timed handling of file delete/save is based on nested promise chains.如上面的代码所示,文件删除/保存的正确定时处理是基于嵌套的 promise 链。 In order to free the programmers' minds from writing and maintaining such structures the async... await syntax was introduced.为了将程序员的注意力从编写和维护此类结构中解放出来,引入了async... await语法

The next code example repeats the above code block, just in a more imperative programming style...下一个代码示例重复上面的代码块,只是以一种更加命令式的编程风格......

 async function callAttachmentWS(action, project, fileName) { return new Promise( (resolve, reject) => { setTimeout(() => { // file deletion completed. resolve({ action, fileName }); }, 3000); } ); } function triggerFileActions(action, fileList) { console.log(`+++ trigger ${ action.toLowerCase() } files +++`); // returns an array of promises. return fileList.map(fileName => callAttachmentWS(action, 'my-project-name', fileName) ) } async function deleteFiles(fileList) { // returns a promise. return Promise.allSettled(triggerFileActions('DELETE', fileList)); } async function saveFiles(fileList) { // returns a promise. return Promise.allSettled(triggerFileActions('SAVE', fileList)); } async function handleFileDeleteAndFileSave(deleteList, saveList) { // handles promises (async functions) via `await` syntax, // thus it makes it an async function too // which (implicitly) returns a promise. const deleteResultList = await deleteFiles(deleteList); deleteResultList.forEach(result => console.log(result)); console.log('... delete files finished...'); const saveResultList = await saveFiles(saveList); saveResultList.forEach(result => console.log(result)); console.log('... save files finished...'); return '+++ handleFileDeleteAndFileSave is settled +++'; } const filesToDelete = ['foo', 'bar', 'baz']; const programs = ['bizz', 'buzz']; (async function () { const status = await handleFileDeleteAndFileSave(filesToDelete, programs); console.log(status); }());
 .as-console-wrapper { min-height: 100%;important: top; 0; }

You can use async/await.您可以使用异步/等待。 Here is more about them这是关于他们的更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM