简体   繁体   English

如何在 for 循环中的下一次迭代之前等待 promise 解决

[英]How to wait for a promise to resolve before the next iteration in for loop

I have got two data tables I want to query some data from, so the way i thought about doing it is fetch url and based on a field from list, I do fetch(url) once more to get related data from another data table and I want to append them together to display on the browser.我有两个数据表我想从中查询一些数据,所以我想到的方法是获取 url 并基于列表中的一个字段,我再次 fetch(url) 以从另一个数据表中获取相关数据和我想把append它们一起显示在浏览器上。 The issue here is that for loop iteration doesn't wait until the previous fetch is finished.这里的问题是 for 循环迭代不会等到上一次 fetch 完成。 I am using django_restframework, and it is me trying to fetch data by passing criteria(variables) through urls.我正在使用 django_restframework,我试图通过 url 传递标准(变量)来获取数据。 can anyone help?谁能帮忙?

var url = 'http://127.0.0.1:8000/creditor-detail/'+pmt_id+'/supplier/'+crm_spplier_id+'/'

var results = fetch(url)
      .then((resp) => resp.json())
      .then(function(item){ 

        var list = item
        for (var i in list){

                    getCustomer(list[i].customer_id)
                    .then(function test(user) {
                    return user[0].customer_name
                   
                  });

                var spmt = `
                    <tr id="data-row-${i}">
                        <td>${list[i].po_no}</td>
                        <td>${list[i].amount}</td>                  
                        <td>${I want return value[user[0].customer_name]}</td>
                    </tr>
                `
                wrapper.innerHTML+= spmt
        }
      })





  function getCustomer(customer_id){
    var url = 'http://127.0.0.1:8000/user-detail/'+customer_id+'/'

    var results = fetch(url)
                  .then((resp) => resp.json())
                  .then(function(item){

                      return item       
                  })
  return results
}

I have changed to:我已更改为:

    function test() {
      const url = 'http://127.0.0.1:8000/creditor-detail/'+pmt_id+'/supplier/'+crm_supplier_id+'/'
      let promises = [];

      const results = fetch(url)
      .then(resp => resp.json())
      .then(function (item) {

        var list = item;
   
        for (var i in list) {
          promises.push(getCusotmer(list[i].customer_id));
          console.log(list[i].customer_id)

        }
      })
      
      Promise.all(promises)
          .then((results) => {
            console.log("All done", results);
          })
          .catch((e) => {
            
            console.log(err)
          });
    }
    
    


    function getCusotmer(customer_id) {
    
    return new Promise((resolve, reject) => {
      const url = 'http://127.0.0.1:8000/customer-detail/' + customer_id+ '/';
      fetch(url)
        .then(resp => resp.json())
        .then((item) => resolve(item))
        .catch((err) => {

          console.log(err)
          
          reject(err)
        })
    })
  }

  test();

And the console looks like this:控制台看起来像这样:

All done []length: 0__proto__: Array(0) 1466 1663全部完成 []length: 0__proto__: Array(0) 1466 1663

I thought based on the promise logic, all done should have been read in the end, am I missing anything here?我认为基于 promise 逻辑,所有完成的都应该最终阅读,我在这里遗漏了什么吗?

It's hard to understand the first time, but here I go.第一次很难理解,但这里我是go。 The simple answer is "You can't do that", javascript works with an 'event loop', it's like a thread containing all the tasks javascript is going to do, when you use an asynchronous task like 'search' it escapes the 'event loop' for being asynchronous.简单的答案是“你不能那样做”,javascript 使用“事件循环”,它就像一个包含 javascript 将要执行的所有任务的线程,当您使用像“搜索”这样的异步任务时,它会转义“事件循环'是异步的。 But the 'for loop' is not asynchronous so it will be processed in the 'Event Loop'.但是“for 循环”不是异步的,因此它将在“事件循环”中处理。 This means that 'fetch' will exit the 'Event Loop' and when its request is completed it will return to the 'Event Loop', in this moment, the 'for loop' was terminate.这意味着'fetch'将退出'Event Loop',当它的请求完成后,它将返回'Event Loop',此时'for循环'被终止。

But don't worry, you can solve it, how?不过不用担心,你可以解决它,怎么解决? well, you can iterate the loop and save a new array of promise, await for all of them will complete and in this moment create your 'tr' row好吧,您可以迭代循环并保存一个新的 promise 数组,等待所有这些都将完成,此时创建您的“tr”行

Its an example with your code: The first function could be like this:这是您的代码示例:第一个 function 可能是这样的:

const promises = [];
fetch(url)
  .then(resp => resp.json())
  .then((item) => {
    const list = item;
    for (let i in list) {
      promises.push(getCustomer(list[i].customer_id))
    }
    Promise.all(promises).then((resolveAllData) => {
      //Do all that you need with your data
      //Maybe you can use a for loop for iterate 'responseAllData
    });
  }).catch((err) => {
    //manage your err
  })


And the second function could be like this:第二个 function 可能是这样的:

function getCustomer(customer_id) {
  return new Promise((resolve, reject) => {
    const url = 'http://127.0.0.1:8000/user-detail/' + customer_id + '/';
    fetch(url)
      .then(resp => resp.json())
      .then((item) => resolve(item))
      .catch((err) => {
         //manage your err
         reject(err)
      })
  })
}

A recommendation, learn how JavaScript works and its asynchronism, try not to use 'var', to get better performance and have no problems with scope一个建议,学习 JavaScript 的工作原理及其异步性,尽量不要使用 'var',以获得更好的性能并且与 scope 没有问题

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

相关问题 如何使循环等待db promise完成,然后再继续下一次迭代? - How do I make for loop wait for db promise to finish before it continues to next iteration? 如何等到 promise 完成后再开始 JavaScript 中的“无限”for 循环的下一次迭代 - How to wait until a promise is completed before starting the next iteration of an “infinite” for loop in JavaScript 如何进行循环以等待元素,然后再进行下一次迭代 - How to make for loop wait for an element before moving to next iteration 在下一次循环迭代之前等待承诺结果 - await promise result before next loop iteration 在 for 循环的下一次迭代之前完成承诺? - Complete promise before next iteration of for loop? 我如何让 javascript 循环在开始下一次循环之前等待循环的每次迭代完成? - How do i make javascript loop wait for each iteration of loop to finish before starting the next? 在 Node.js 的循环中移动到下一次迭代之前等待 Promise - Waiting for Promise before moving to next iteration in a loop in Node.js 等到 http 收到请求,然后再进行下一个循环迭代 - wait until http gets request before moving to next loop iteration 强制循环等待mysql插入,然后再进行下一次迭代 - Force loop to wait for mysql insert before moving to next iteration 在移动到循环的下一次迭代之前等待文件上传? - Wait for file to be uploaded before moving to the next iteration of loop?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM