WooHee
WooHee

Reputation: 1

How can i refactor my async code in javascript (I'm using Promise)

dbConnect(res).then((conn)=>{
query(conn,res,
  `SELECT * FROM programs WHERE user_id = ?`,
  [
    user_id
  ]
).then((programList)=>{

  new Promise((resolved,rejected)=>{
    for(let i = 0; i<programList.length;i++){
      query(conn,res,`
        SELECT * FROM open_programs WHERE program_id = ?`,[programList[i].program_id])
      .then((opList)=>{
        Object.assign(programList[i],{openList : opList});
        console.log(programList[i]);
        if(i == (programList.length-1)){
          resolved(programList)
        }
      })
    }
  }).then((result)=>{
    conn.release();
    res.json(toRes(SUCCESS,
      { data : result }
    ));
  })
});
});

'dbConnect', 'query' is my custom method that consist of 'Promise'

In this code, first i get firstResults(schema=programs) after i get nextsqlResults using firstResults.program_id in 'for loop' and Object assign firstresult and nextResults

after assigning, I response the combined data

How can i develop this code?

Upvotes: 0

Views: 252

Answers (2)

haotang
haotang

Reputation: 5698

@Andy Ray provided a nice solution. I just want to add some additional improvement.

In other to make thing readable, by extracting your existing code into smaller function you can organize your code like this:

connectDb(res)
    .then(selectPrograms)
    .then(populateOpenPrograms)
    .then(handleResult);

And if you want to improve it more, consider using async / await

Upvotes: 0

Andy Ray
Andy Ray

Reputation: 32066

Promise.all and Array.map will help you here. Untested:

dbConnect(res).then(conn => {
    return query(conn, res, `SELECT * FROM programs WHERE user_id = ?`, [
        user_id,
    ]);
}).then(programList => {
    return Promise.all(programList.map( program => 
        query(
            conn,
            res,
            `SELECT * FROM open_programs WHERE program_id = ?`,
            [program.program_id],
        ).then(opList => {
            console.log(program);
            return Object.assign(program, { openList: opList });
        });
}).then(result => {
    conn.release();
    res.json(toRes(SUCCESS, { data: result }));
});

You should verify that result is the data structure you're looking for after this code.

Cleaned up a little more with the babel-plugin-transform-object-rest-spread plugin:

dbConnect(res).then(conn =>
    query(conn, res, `SELECT * FROM programs WHERE user_id = ?`, [
        user_id,
    ])
).then(programList =>
    Promise.all(programList.map(program => 
        query(
            conn,
            res,
            `SELECT * FROM open_programs WHERE program_id = ?`,
            [program.program_id],
        ).then(opList => ({
            ...program,
            openList: opList
        })
    ))
).then(result => {
    conn.release();
    res.json(toRes(SUCCESS, { data: result }));
});

Upvotes: 1

Related Questions