Search code examples
javascriptnode.jsasync-awaites6-promiseecmascript-2017

Await for asynchronous function results in undefined


I'm having trouble with async/await with Node. When I try this:

function Read_Json_File() {
   fs.readFile('import.json','utf-8',(err, data) => {  
       if (err) throw err;
       json_data = JSON.parse(data);

       return json_data;

   });
}

async function run_demo() {
    let get_json_file = await Read_Json_File();
    console.log(get_json_file);
}

run_demo();

It returns undefined instead of the JSON from the file. Why doesn't it wait for the file reading to finish?


Solution

  • You're not returning anything from Read_Json_File, thus you get undefined -- you're returning data from the callback which doesn't result in anything. Instead, to use async/await, you'd need to promisify fs.readFile since it's not already. Then you'll be able to use async/await:

    function readJSONFile() {
      return new Promise((resolve, reject) => {
        fs.readFile('import.json', 'utf-8', (err, data) => { 
          if (err) reject(err);
          resolve(JSON.parse(data));
        });
      });
    }
    

    Await requires an actual promise to wait for. What this does is return a promise to use await on. Thus, we wait until we call resolve - which happens when we're done loading the JSON:

    let json = await readJSONFile();
    console.log(json);
    

    Here we call readJSONFile. This returns a promise which resolves when the JSON file is done loading, and allows for seemingly synchronous execution of asynchronous code.