Hiperfly
Hiperfly

Reputation: 178

Async function returns empty array

I'm trying to create a matrix of some pairs of data. fetchDataPair() is an async function.

async function fetchData(info_array){
    let matrix = []
    for(const i of info_array){
        let row = []
        for (const j of info_array){
            if (i != j){
                let pair = fetchDataPair(i,j)
                row.push(pair)
            }else{
                row.push(null)
            }
        }
        Promise.all(row).then((resolvedRow)=>{ //resolve all the promises in the row, then push to matrix
            matrix.push(resolvedRow)
        })
    }
    //matrix should be an array of arrays of (resolved) promises, but it just returns an empty array
    console.log(matrix) //logs []
    return matrix
}

This code unfortunately seems to reach return matrix before the rows are pushed into the array, but I can't understand why.

Thanks

EDIT: Fixed the name of the inside function from fetchData to fetchDataPair

Upvotes: 1

Views: 486

Answers (2)

Eduard Hasanaj
Eduard Hasanaj

Reputation: 895

There are a couple mistakes in the code. The problem is that you need to wait on Promise.all. If you use .then you are subscribing to be notified when it is finished but the execution continues and the console is printed before the promise finishes the execution.

async function fetchData(info_array){
    let matrix = [];
    for(const i of info_array){
        let row = []
        for (const j of info_array){
            if (i != j){
                let pair = fetchData(i,j)
                row.push(pair)
            }
            else {
                row.push(null);
            }
        }

        const rowProc = await Promise.all(row);
        matrix.push(rowProc);
    }
    
    console.log(matrix)
    return matrix
}

Upvotes: 0

Bergi
Bergi

Reputation: 664650

//resolve all the promises in the row, then push to matrix

That has exactly the same problem as would waiting for the pair promise resolve and pushing its result to the row array afterwards - you can't do that, you need to create an array of promises and use Promise.all:

function fetchData(info_array) {
    let matrix = []
    for (const i of info_array) {
        let row = []
        for (const j of info_array) {
            if (i != j) {
                let pair = fetchDataPair(i,j)
                row.push(pair)
            } else {
                row.push(null)
            }
        }
        matrix.push(Promise.all(row))
//      ^^^^^^^^^^^^                ^
    }
    return Promise.all(matrix)
//         ^^^^^^^^^^^
}

Upvotes: 1

Related Questions