I have a problem with promised array: I'm calling inside my switch a function which is loading an array from API Example:
let sorted = []
let limit = 10
async function loadPage(slcLimit) {
let i
let filter = document.getElementById("show-filter").value
if (sorted.length == 0) {
switch (filter) {
case "1":
let realWoolPromiseAsc = await Promise.resolve(realWool(pagingPouches))
.then((realWoolArr) => {
sorted = realWoolArr.sort((a, b) => parseFloat(a.realWool) - parseFloat(b.realWool));
return sorted
})
break;
case "2":
let realWoolPromiseDesc = await Promise.resolve(realWool(pagingPouches))
.then((realWoolArr) => {
sorted = realWoolArr.sort((a, b) => parseFloat(b.realWool) - parseFloat(a.realWool));
return sorted
})
break;
}
}
for (i = startingLimit; i < (startingLimit + limit); i++) {
console.log(sorted[i].ID + " - " + sorted[i].price)
}
}
Real wool function
window.realWool = async function realWool(pouchArr) {
let divider = 1000000000000000000n;
let realWoolArray = []
pouchArr.forEach(async pouch => {
let availAmount = await pouchContract.amountAvailable(pouch.pouchID)
availAmount = Number(BigInt(availAmount.toString()) * 100n / divider) / 100
availAmount = Math.floor(availAmount * 100) / 100
let rWool = pouch.pouchWool - availAmount
realWoolArray.push({pouchID: pouch.pouchID, realWool: rWool, pouchTime: pouch.pouchTime})
//document.getElementById("lockedText" + pouch.pouchID).innerHTML = "Real WOOL: <span class='black'>" + rWool + "</span>"
});
return realWoolArray
}
I need to use the sorting array inside my for loop but I'm getting undefined. I understand I need to use await or a then block I just have no clue how to use that.
Thank you!
I've used a timeout , but it is not optimal since sometimes the function just return an array of 5 objects and sometimes a hundreds of objects (depends on filters)
setTimeout(() => {
for (i = startingLimit; i < (startingLimit + limit); i++) {
console.log(sorted[i].ID + " - " + sorted[i].price)
}
}, 5000);
You need to return from the then
block.
And spell length
correctly.
You do not need to set the module scoped sorting
in the then
block either.
let promisedArray = await Promise.resolve(myFunction())
.then((realArray) => {
sorting = realArray.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));
return sorting // <-- return to awaited value
})
for (let i = 0; i < promisedArray.length; i++) { <-- check spelling
console.log(promisedArray[i]) //returns the value I need
}
You do not need await Promise.resolve
either, just await realWool
.
Your problem is here: pouchArr.forEach(async pouch => {...})
this is a fire and forget situation. forEach
will start all the tasks at once and then as soon as all have started, forEach is done and your code goes to the next command return realWoolArray
before even the first entry has been added.
Then in loadPage
your sort will sort a (currently) empty array, ... and when all your synchronous code is done, and the Promises start to resolve, your code pushes the items all the way into the sort
array.
window.realWool = async function realWool(pouchArr) {
const divider = 1000000000000000000n;
return Promise.all(
pouchArr.map(async (pouch) => {
let availAmount = await pouchContract.amountAvailable(pouch.pouchID)
availAmount = Number(BigInt(availAmount.toString()) * 100n / divider) / 100;
return {
pouchID: pouch.pouchID,
realWool: pouch.pouchWool - availAmount,
pouchTime: pouch.pouchTime
}
})
);
}
The array sorted
that you use in the loadPage
function is a global variable, which means that all invocations of loadPage
(I assume that each incoming request causes one invocation) will access the same array concurrently. This cannot lead to correct (or even predictable) results.
Put the let sorted = []
inside the function body to make it local. And the function must return something, for example return realWoolPromiseAsc
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.