The problem of asynchronously constructing data return sets containing objects by js

problem description

I need to make a return dataset, which is an object array awardList, in which each object has className property and stuInfo property, stuInfo property is an object array, and then the object properties in it are name and awardInfo. These objects and arrays are constructed. I fill them one by one with the data queried from the database. After the code I wrote is executed, I find that awarsList is still an empty array. It still feels like an asynchronous problem, but I can"t find out what the problem is.

the environmental background of the problems and what methods you have tried

was previously used as a callback function, but was later rewritten as Promise

related codes

/ / Please paste the code text below (do not replace the code with pictures)

let getClassInfo=function (jobId) {

let sql=`SELECT
        counselorclasscontact.classId,
        class.className
    FROM
        counselorclasscontact,
        class
    WHERE    
        class.classId=counselorclasscontact.classId
    AND
        counselorclasscontact.jobId = ?`;
return new Promise(function(resolve,reject){
    db.query(sql,[jobId],function (results,field) {
        try {
            resolve(results)
        }catch (err) {
            reject(err)
        }
    })
})

}

let getStuInfo=function (classId) {

let sql=`SELECT
        DISTINCT awardinformation.studentId,
        student.name
    FROM
        student,
        awardinformation
    WHERE    
        awardinformation.classId=?
    AND 
      awardinformation.studentId=student.studentId`;
return new Promise(function(resolve,reject){
    db.query(sql,[classId],function (results,field) {
        try {
            resolve(results)
        }catch (err) {
            reject(err)
        }
    })
})

}
let getStuAwardInfo=function (studentId) {

let sql=`SELECT
        awardinformation.awardName,
        awardinformation.awardTime,
        awardinformation.awardAgency
    FROM
        awardinformation
    WHERE    
        awardinformation.studentId=?`;
return  new Promise(function (resolve,reject) {
        db.query(sql,[studentId],function (results,field) {
            try {
                resolve(results)
            }catch (err) {
                reject(err)
            }
        })
    })

}

exports.getAwardByCounselor = function (send,jobId) {

let awardInfoList=[];
//let classResult=await getClassInfo(jobId);
getClassInfo(jobId).then(function (classResult) {
    for(let i=0;i<classResult.length;iPP){
        getStuInfo(classResult[i].classId).then(function (stuResult) {
            let awardInfoByClass={
                className:"",
                stuInfo:[]
            };
            awardInfoByClass.className=classResult[i].className;
            if(stuResult.length!==0) {
                for (let i = 0; i < stuResult.length; iPP) {
                    let singleStuInfo = {
                        stuName: "",
                        awardInfo: []
                    }
                    singleStuInfo["stuName"] = stuResult[i].name;
                    getStuAwardInfo(stuResult[i].studentId).then(function (singleAwardInfo) {
                        for (let i = 0; i < singleAwardInfo.length; iPP)
                            singleStuInfo["awardInfo"].push(singleAwardInfo[i]);
                        awardInfoByClass["stuInfo"].push(singleStuInfo);
                        //console.log(awardInfoByClass);
                        //send(awardInfoByClass);

                    }, function (error) {
                        console.log(error);
                        let results = "error"
                        send(results)
                    })
                    //console.log(awardInfoByClass);
                }

            }
            //console.log(awardInfoByClassz);
            awardInfoList.push(awardInfoByClass);
        },function (error) {
            console.log(error);
            let results="error"
            send(results)
        })

    }
    console.log(awardInfoList);
    send(awardInfoList);
},function (error) {
    console.log(error);
    let results="error"
    send(results)
})

}

what result do you expect? What is the error message actually seen?

the expected result is that there is content in awardList, and there is also content in nested objects.

Jul.05,2022

error:

return new Promise(function(resolve,reject){
    db.query(sql,[jobId],function (results,field) {
        try {
            resolve(results)
        }catch (err) {
            reject(err)
        }
    })
})

first of all, the first parameter of the callback function must be error, which means that your results here is not the result you expect, but an error message in case of an error.
secondly, try. Catch doesn't work here, and the error you want to catch should be the exception that might be thrown by db.query, which corresponds to the first parameter of the callback, but you catch resolve.

Correction:

return new Promise(function(resolve,reject){
    db.query(sql,[jobId],function (err, results,field) {
        if (err) reject(err);
        resolve(results);  
    })
})

resolved!
the source code is as follows:

let getClassInfo=async (jobId)=>{
    let sql=`SELECT
            college.collegeName,
            counselorclasscontact.classId,
            class.className
        FROM
            counselorclasscontact,
            class,
            college
        WHERE
            class.classId = counselorclasscontact.classId
        AND class.collegeId = college.collegeId
        AND counselorclasscontact.jobId = ?`;
    return new Promise(async(resolve,reject)=>{
        try {
            let classResult=await db.queryByPromise(sql,jobId);
            let parseReuslt=JSON.parse(JSON.stringify(classResult));
            resolve(parseReuslt);
        }catch (e) {
            reject(e);
        }
    })
}

    let getStuInfo=async(classId)=>{
    let sql=`SELECT
            DISTINCT awardinformation.studentId,
            student.name
        FROM
            student,
            awardinformation
        WHERE    
            awardinformation.classId=?
        AND 
          awardinformation.studentId=student.studentId`;
    return new Promise(async(resolve,reject)=>{
        try {
            let stuInfo=await db.queryByPromise(sql,classId);
            let parseReuslt=JSON.parse(JSON.stringify(stuInfo));
            resolve(parseReuslt);
        }catch (e) {
           reject(e);
        }
    })
}


let getStuAwardInfo=async(studentId)=>{
    let sql=`SELECT
            awardinformation.awardName,
            awardinformation.awardTime,
            awardinformation.awardAgency
        FROM
            awardinformation
        WHERE    
            awardinformation.studentId=?`;

    return  new Promise(async(resolve,reject)=> {
        try {
            let stuAwardList=await db.queryByPromise(sql,studentId);
            let parseReuslt=JSON.parse(JSON.stringify(stuAwardList));
            resolve(parseReuslt);
        }catch (e) {
            reject(e);
        }
    })
}

exports.getAwardByCounselor = async(jobId)=> {
    return new Promise(async(resolve,reject)=>{
        try {
            let classInfo=await getClassInfo(jobId);
            for(let i=0;i<classInfo.length;iPP){
                classInfo[i].stuInfo=[];
                let stuInfo=await getStuInfo(classInfo[i].classId);
                if(stuInfo.length!==0){
                    stuInfo.forEach(item=>{
                        classInfo[i].stuInfo.push(item);
                    })
                }
                if(classInfo[i].stuInfo.length!==0){
                    console.log(classInfo[i].stuInfo);
                    for(let j=0;j<stuInfo.length;jPP){
                        let awardInfo=await getStuAwardInfo(stuInfo[j].studentId);
                        classInfo[i].stuInfo[j].Info=[];
                        for(let k=0;k<awardInfo.length;kPP){
                            classInfo[i].stuInfo[j].Info.push(awardInfo[k]);
                        }
                    }
                }
            }
            resolve(classInfo);
        }catch (e) {
            reject(e);
        }
    })

}

idea: is not much different from the proposed problem code, except that the original main function code uses callback functions to solve the problem. I changed it all to Promise and combined with async syntax candy to make the code look more synchronized. Finally, after inquiring, I learned that the error is that I defined an awardInfoList array in the function getAwardByCounselor () in the question, which is used to carry the results returned and built by the asynchronous function. In the last step send (awardInfoList) , because it is synchronous code, it is executed directly before the asynchronous function is finished, resulting in the final data set empty. After the improvement, we directly use the first step to obtain class information function getClassInfo () to build the result set, and call it layer by layer.

Menu