以固定顺序执行异步功能javascript

时间:2020-07-09 14:03:01

标签: javascript function async-await

我有 3个功能,我想以固定顺序(f1,f2,f3)执行它们。我尝试过异步等待和承诺,第一种方法行不通,第二种方法我猜不明白。

第一个函数将本地路径推送到名为“ jsons”的数组,第二个函数将数据从路径推送至名为“ profile”的数组,第三个函数将数组“ profile”发送至url。 我知道这可能不是最安全的方法,但这只是一个小项目,可以更好地了解js。

function visualroute() { 

  const jsons = [];
  const profile = [];

  router.get('/user', verify, async (req, res) => {//here i want the data to be sent to
    
    //Push array jsons
    const checker = async function (){
      sqldb.query(`SELECT * FROM ${username}`, (error, result) =>{
      console.log('1');
        if(error) {
          console.log(error);
        }
        if( result.length == 0 ) {
          console.log('User does not have initiated a db yet');
          return res.render('user/index', {
            message: 'No data added to db yet'
          });
        } else {
          try{        
            //for loop to push the required info into jsons[]
            for(i=0; i<result.length; i++){
              jsons.push(`../public/jsonsheets/${result[i].infoticker}.json`);
            }
            console.log(jsons);
          } catch(err){
            throw err;
          } 
        };//else end
      });//checker end
    }

    //push array profile
    const jsonreader = async function() {
      console.log('2');
      for(i=0; i<jsons.lenght; i++){
        //Check if path exists
        try {
          fs.access(`public/jsonsheets/${jsons[i]}`, fs.F_OK, (err) => {
            if (err) {
              console.log('Does not exist');
              return
            }
            console.log('Exists');

            //exists: read it into profile[]
            fs.readFile(`public/jsonsheets/${jsons[i]}`, (err, data) => {
              if (err) throw err;
              let userdata = JSON.parse(data);

              profile.push(userdata);
              
            });
          })
        } catch(err) {
          console.log(err)
        }
      }//for loop end
      
      console.log(profile);
    }

    // send data to url
    const finalsender = async function() {
      console.log('3');
      res.send(
        profile
      );
    }  
    
    async function quefunction(){
      await checker();
      await jsonreader();
      await finalsender();
    }

    quefunction();
    
  }); //route end
}; //visualroute end

visualroute();

我的输出:2、3、1,因此接收网址上的数组为空。

1 个答案:

答案 0 :(得分:0)

正如克里斯所说,第一个和第二个函数需要返回promise。
因为它们的主体包含异步函数(例如db.query和fs.access),并且在异步函数中返回结果(降低结果)的唯一方法是调用resolve()。

请参阅下文。

const jsons = [];
const profile = [];

router.get('/user', verify, async (req, res) => {//here i want the data to be sent to
  
  //Push array jsons
  const checker = async function (){
    return new Promise((resolve, reject) => { // return Promise
        sqldb.query(`SELECT * FROM ${username}`, (error, result) =>{
            // console.log('1');
              if(error) {
                console.log(error);
                reject(error); // reject here to quit processing
              }
              if( result.length == 0 ) {
                console.log('User does not have initiated a db yet');
                res.render('user/index', {
                  message: 'No data added to db yet'
                });
                reject('no user invited'); // no need to process more
              } else {
                try{        
                  //for loop to push the required info into jsons[]
                  for(i=0; i<result.length; i++){
                    jsons.push(`../public/jsonsheets/${result[i].infoticker}.json`);
                  }
                  console.log(jsons);
                  console.log(1)
                  resolve(); // resolve and then next function call starts.
                } catch(err){
                  //throw err;
                  reject(err);
                } 
              };//else end
            });//checker end
    })

  }

  //push array profile
  const jsonreader = async function() {
    return new Promise((resolve, reject) => {
        console.log('2');
        for(i=0; i<jsons.lenght; i++){
          //Check if path exists
          try {
            fs.access(`public/jsonsheets/${jsons[i]}`, fs.F_OK, (err) => {
              if (err) {
                console.log('Does not exist');
                reject(err);
              }
              console.log('Exists');
  
              //exists: read it into profile[]
              fs.readFile(`public/jsonsheets/${jsons[i]}`, (err, data) => {
                if (err) throw err;
                let userdata = JSON.parse(data);
                profile.push(userdata);
                resolve();                    
              });
            })
          } catch(err) {
            console.log(err)
            reject(err)
          }
        }//for loop end
    })        
  }

  // send data to url
  const finalsender = async function() {
    console.log('3');
    res.send(
      profile
    );
  }  
  
  async function quefunction(){
    try {
        await checker();
        await jsonreader();
        await finalsender();
    } catch(err) {
        // all reject function call will jump to here
        console.error(err);
    }

  }

  quefunction();
  
 }); //route end
}; //visualroute end

visualroute();