[英]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.