1

Variables declared inside a Promise get returned first and then the function gets executed

I have the following piece of code which first gets some filter values and pushes them into filterFetchPromises. The function of getting the filters in itself is an asynchronous function. Then I process the data inside filterFetchPromises and then I have to return the processed data. The variables used for storing the processed data are declared within the getfilters() function because I need them to set to empty after every iteration.

Currently, when I print out the filter names, filter values, they just show empty. How do I process the data from filterFetchPromises first and then return those values?

function getfilters() {
 return new Promise(function(resolve) {
 let filterFetchPromises = [];
 let dashboardfilters = [];
 let filternames = [];
 let filtervalues = []; 
 filterFetchPromises.push(worksheet.getFiltersAsync());
 Promise.all(filterFetchPromises).then(function (fetchResults) {
 fetchResults.forEach(function (filtersForWorksheet) {
 filtersForWorksheet.forEach(function (filter) {
 dashboardfilters.push(filter);
 if (contains(filternames, filter.fieldName)) {
 console.log("Duplicate Entry")
 }
 else {
 let filtervalues_temp = []
 console.log(filter.fieldName)
 if ((filter.appliedValues).length > 0) {
 filternames.push(filter.fieldName)
 console.log(filter.fieldName)
 filter.appliedValues.forEach(function(test) {
 console.log(test.value)
 filtervalues_temp.push(test.value)
 })
 filtervalues.push(filtervalues_temp)
 }
 } 
 });
 });
 });
 // console.log(filternames)
 // console.log(filtervalues)
 return resolve([filternames, filtervalues]);
 })
}
getfilters().then(function ([filternames, filtervalues]) {
 console.log("Function got over.")
 console.log(filternames)
 console.log(filtervalues)
})

Currently, filter names and filter values are empty. I just want the data to be processed first and then print those variables

Sujal Patel
2,5402 gold badges21 silver badges40 bronze badges
asked Jun 7, 2019 at 5:24
2
  • 4
    java != javascript Commented Jun 7, 2019 at 5:29
  • Try return inside Promise.all() Commented Jun 7, 2019 at 5:36

2 Answers 2

1

You need to keep in mind that Javascript is async and hence your resolve([filternames, filtervalues]); will be called before their values get updated in promise.all.

As per MDN's definition of Promise, the data with which you call the resolve function is the data this promise gets resolved to and hence there is no need to return something.

Move the resolve call inside your promis.all after your filternames and filtervalues get updated.

Try the following code:

function getfilters() {
 return new Promise(function(resolve) {
 let filterFetchPromises = [];
 let dashboardfilters = [];
 let filternames = [];
 let filtervalues = []; 
 filterFetchPromises.push(worksheet.getFiltersAsync());
 Promise.all(filterFetchPromises).then(function (fetchResults) {
 fetchResults.forEach(function (filtersForWorksheet) {
 filtersForWorksheet.forEach(function (filter) {
 dashboardfilters.push(filter);
 if (contains(filternames, filter.fieldName)) {
 console.log("Duplicate Entry")
 }
 else {
 let filtervalues_temp = []
 console.log(filter.fieldName)
 if ((filter.appliedValues).length > 0) {
 filternames.push(filter.fieldName)
 console.log(filter.fieldName)
 filter.appliedValues.forEach(function(test) {
 console.log(test.value)
 filtervalues_temp.push(test.value)
 })
 filtervalues.push(filtervalues_temp)
 }
 } 
 });
 resolve([filternames, filtervalues]);
 });
 });
 // console.log(filternames)
 // console.log(filtervalues)
 })
}
getfilters().then(function ([filternames, filtervalues]) {
 console.log("Function got over.")
 console.log(filternames)
 console.log(filtervalues)
})
answered Jun 7, 2019 at 5:43
Sign up to request clarification or add additional context in comments.

Comments

1

You should resolve your top level promise with the return value only when your asynchronous operation is complete. In your code, you are doing it before the async operation is complete. Call the resolver right after you populate the arrays.

fetchResults.forEach(function (filtersForWorksheet) {
 ...
 ...
});
resolve([filternames, filtervalues]);
answered Jun 7, 2019 at 5:50

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.