3

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"
}
ryan
  • 503
  • 2
  • 7
  • 17
  • 1
    What is `raw` exactly? Provide a complete runnable example that demonstrates your problem. – zerkms Jun 06 '17 at 03:09
  • The code you present will cause an error, not output "undefined" as you claim, because `raw` is not defined in the call `test(raw)` – Jaromanda X Jun 06 '17 at 03:16
  • @JaromandaX Maybe that confuses people :) I just assumed I provide correct raw input hehe changed now – ryan Jun 06 '17 at 03:28
  • 1
    see how the full context of the code explains why the function returns undefined, because it actually returns undefined! – Jaromanda X Jun 06 '17 at 03:31

1 Answers1

6

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');
Soviut
  • 88,194
  • 49
  • 192
  • 260
  • 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 Jun 06 '17 at 03:09
  • So I think "return" does not wait JSON.parse result. – ryan Jun 06 '17 at 03:09
  • @ryan "I think "return" does not wait JSON.parse result" --- it's impossible – zerkms Jun 06 '17 at 03:09
  • 2
    @ryan return always waits, unless you explicitly make something async, it's synchronous. – Soviut Jun 06 '17 at 03:10
  • @zerkms I see... so it is not possible to return JSON.parse result...? – ryan Jun 06 '17 at 03:11
  • 1
    @ryan no, it's not possible that what you assume is true. – zerkms Jun 06 '17 at 03:11
  • @ryan please update your original question with an example of what `raw` looks like. – Soviut Jun 06 '17 at 03:12
  • 1
    @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. – zerkms Jun 06 '17 at 03:20
  • @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. – ryan Jun 06 '17 at 03:26
  • @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). – Paul Jun 06 '17 at 03:28
  • @Paulpro what do you mean I don't have return statement in test function..?? return JSON.parse(content)); – ryan Jun 06 '17 at 03:29
  • @ryan That's in an anonymous function, not in the function `test`. – Paul Jun 06 '17 at 03:30
  • @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! – ryan Jun 06 '17 at 03:39
  • 1
    @ryan You're welcome, I hope you found a good solution to achieve your desired outcome in the duplicate :) – Paul Jun 06 '17 at 03:40
  • console.log is definitely not synchronous! I had loads of problems trying to debug values because 'future' values were logged. – Eggon Dec 26 '21 at 18:33
  • @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. – Soviut Dec 26 '21 at 23:30
  • @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. – Eggon Dec 27 '21 at 11:03