How to make JSON.parse promise? (or asynchronous)

15,912

JSON.parse() is indeed synchronous, so is console.log(), so is the return statement. Everything in Javscript is synchronous (and single threaded) unless you explicitly make it asynchronous.

You're getting an undefined because the whatever you passed in raw to JSON.parse() wasn't valid JSON or it was empty or maybe it wasn't actually a string.

Here is a live example to show it running synchronously.

function test(raw) {
  return JSON.parse(raw);
}

console.log('this happens first');
console.log(test('{"valid1": true}'));
console.log('this happens 3rd');
console.log(test('{"valid2": true}'));
console.log('this happens last');

Share:
15,912

Related videos on Youtube

ryan
Author by

ryan

Updated on June 04, 2022

Comments

  • ryan
    ryan almost 2 years

    I am trying to make a function which returns result of JSON.parse. Following is example code:

    function test(raw) {
     return JSON.parse(raw);
    }
    
    // assume I provide valid raw_input...
    console.log(test(raw_input));
    // expect json object but it says "undefined"...
    

    I think I know why (please correct me if I am wrong). JSON.parse is not asynchronous... it returns its result when it is ready. And console.log doesn't wait for its result... more like console.log thinks it is done, so it says "undefined".

    Here is my question... how can you make JSON.parse promise? Or asynchronous? Like how can you make "return" in the function to wait result of JSON.parse?

    If you can provide simple promise codes... that would be really helpful. Thank you so much in advance. (I am open to bluebird js or async/await or etc...)

    ADDING codes (more about raw)

    In the function, I am reading json file, then JSON.parse it, then return the result. (source is the path to the json file)

    function test(source) {
    fs.readFile(source, function (err, content) {
    return JSON.parse(content));
    });
    }
    console.log(test('test.json'));
    // it says
    // undefined
    

    json file looks like this (test.json)

    {
    "a": "apple",
    "b": "banana",
    "c": "cat"
    }
    
    • zerkms
      zerkms almost 7 years
      What is raw exactly? Provide a complete runnable example that demonstrates your problem.
    • Jaromanda X
      Jaromanda X almost 7 years
      The code you present will cause an error, not output "undefined" as you claim, because raw is not defined in the call test(raw)
    • ryan
      ryan almost 7 years
      @JaromandaX Maybe that confuses people :) I just assumed I provide correct raw input hehe changed now
    • Jaromanda X
      Jaromanda X almost 7 years
      see how the full context of the code explains why the function returns undefined, because it actually returns undefined!
  • ryan
    ryan almost 7 years
    Thank you for the comment. But I don't agree that my JSON it not valid or empty. For example, if I try console.log(JSON.parse(raw) in my function not returning it, it says JSON object correctly.
  • ryan
    ryan almost 7 years
    So I think "return" does not wait JSON.parse result.
  • zerkms
    zerkms almost 7 years
    @ryan "I think "return" does not wait JSON.parse result" --- it's impossible
  • Sami Ahmed Siddiqui
    Sami Ahmed Siddiqui almost 7 years
    @ryan return always waits, unless you explicitly make something async, it's synchronous.
  • ryan
    ryan almost 7 years
    @zerkms I see... so it is not possible to return JSON.parse result...?
  • zerkms
    zerkms almost 7 years
    @ryan no, it's not possible that what you assume is true.
  • Sami Ahmed Siddiqui
    Sami Ahmed Siddiqui almost 7 years
    @ryan please update your original question with an example of what raw looks like.
  • zerkms
    zerkms almost 7 years
    @Soviut "wasn't valid JSON or it was empty or maybe it wasn't actually a string." --- in that case it would be an exception and the function wouldn't return.
  • ryan
    ryan almost 7 years
    @Soviut After I saw your codes,,, maybe is it because I am using fs.readfile? Like taking too much time... so it console log 'undefined'? In your case, your object is very small one to parse, so it happens almost instantly.
  • Paul
    Paul almost 7 years
    @ryan The timing doesn't matter. You don't have a return statement in your function called test, so it returns the default (undefined). You have a return statement in another function that you define inside test but that doesn't return from test, in fact in this particular case test has been returned from already before the anonymous function is called. See the marked duplicate for more info).
  • ryan
    ryan almost 7 years
    @Paulpro what do you mean I don't have return statement in test function..?? return JSON.parse(content));
  • Paul
    Paul almost 7 years
    @ryan That's in an anonymous function, not in the function test.
  • ryan
    ryan almost 7 years
    @Paulpro Thank you so much! Now I understood. So the outer function ('test' in this case) does not know about 'return statement' in readFile and it just finishes without returning. Thank you again!
  • Paul
    Paul almost 7 years
    @ryan You're welcome, I hope you found a good solution to achieve your desired outcome in the duplicate :)
  • Eggon
    Eggon over 2 years
    console.log is definitely not synchronous! I had loads of problems trying to debug values because 'future' values were logged.
  • Sami Ahmed Siddiqui
    Sami Ahmed Siddiqui over 2 years
    @Eggon not true. Console.log is synchronous. You were most likely logging objects, which browsers often display as live references. These references update as the values change. If you console.log(JSON.stringify(obj)) you won’t log a reference.
  • Eggon
    Eggon over 2 years
    @Soviut Hmm, ok, thanks, yes I was logging objects. And I do remember when I looked for a cause I found some answers on SO saying that console.log is async (and does not evaluate objects instantly) which made perfect sense. I wasn't aware that browsers can log live references. I will play with it.