user12753704
user12753704

Reputation: 23

How to do sequential query execution?

I have such a request:

try {
    /* 1) */
    const dayReports = await DayReport.findAll(query);
    dayReports.forEach((dayReport, index) => {
        /* 2) */
        const findAllYear = DayReport.findAll({
            where: {
                [Op.and]: [
                    {
                        report_date: {
                            [Op.between]: [new Date(dayReport.dataValues.report_date).getFullYear() + '-01-01', dayReport.dataValues.report_date]
                        }
                    }
                ]
            }
        });
        /* 3) */
        var get_sinking_year = 0;
        for (var i = 0; i < findAllYear.length; i++) {
            get_sinking_year += findAllYear[i].dataValues.sinking_day
        } 
        /* 4) */
        console.log(get_sinking_year)
    })
} catch (e) {
    errorHandler(res, e);
}

And I need to execute the request in order, as the numbers in the comments are located (I.e 1,2,3,4.).

Instead, my request is executed in this order 1,3,4,2.

Upvotes: 2

Views: 116

Answers (3)

Stratubas
Stratubas

Reputation: 3067

Try this. It first gathers all the findAllYear results (steps 2), then executes steps 3 and 4 for each result.

try {
    /* 1) */
    const dayReports = await DayReport.findAll(query);

    const allYearArraysPromises = [];
    dayReports.forEach((dayReport, index) => {
        /* 2) */
        const findAllYear = DayReport.findAll({
            where: {
                [Op.and]: [
                    {
                        report_date: {
                            [Op.between]: [new Date(dayReport.dataValues.report_date).getFullYear() + '-01-01', dayReport.dataValues.report_date]
                        }
                    }
                ]
            }
        });
        allYearArraysPromises.push(findAllYear);
    }
    const allYearArrays = await Promise.all(allYearArraysPromises);
    allYearArrays.forEach((findAllYear) => {
        /* 3) */
        var get_sinking_year = 0;
        for (var i = 0; i < findAllYear.length; i++) {
            get_sinking_year += findAllYear[i].dataValues.sinking_day
        } 
        /* 4) */
        console.log(get_sinking_year)
    });
} catch (e) {
    errorHandler(res, e);
}

It's a little different from Tilieth's answer. If you wish to add a 5th step in the future, it would work in the correct order, 12345. With Tilieth's answer, the order would be 12534.

I'm adding some test scripts to illustrate this.

Tilieth's:

async function tilieth() {
  const dayReports = await new Promise(resolve => resolve(['a', 'b', 'c']));
  console.log('Step 1 - Result:', dayReports);
  dayReports.forEach(async(dayReport, index) => {
    console.log('Step 2 for', dayReport);
    const findAllYear = await new Promise(resolve => {
      setTimeout(() => {
        resolve(dayReport);
      }, 500);
    });
    console.log('Steps 3 & 4 for', findAllYear);
  });
  console.log('Step 5');
}
tilieth();

Mine:

async function stratubas() {
  const dayReports = await new Promise(resolve => resolve(['a', 'b', 'c']));
  console.log('Step 1 - Result:', dayReports);
  const allYearArraysPromises = [];
  dayReports.forEach((dayReport, index) => {
    console.log('Step 2 for', dayReport);
    const findAllYear = new Promise(resolve => {
      setTimeout(() => {
        resolve(dayReport);
      }, 500);
    });
    allYearArraysPromises.push(findAllYear);
  });
  const allYearArrays = await Promise.all(allYearArraysPromises);
  allYearArrays.forEach((findAllYear) => console.log('Steps 3 & 4 for', findAllYear));
  console.log('Step 5');
}
stratubas();

Upvotes: 2

kaitlyn
kaitlyn

Reputation: 76

Try using await or promises for "DayReport.findAll()". Also use map instead of for loop.

Upvotes: 0

Tilieth
Tilieth

Reputation: 21

You need to await the result of the query inside the loop. At the moment it's returning a promise and goes straight to the following code.

try const findAllYear = await DayReport.findAll

Upvotes: 1

Related Questions