0

In my honest opinion this question is not duplicated because I know how to fix it using a callback as explain in the linked question, this question is specific about a situation where I cannot modify the outfer function and this is not covered in the another question

I use a library that I cannot modify, the library do something like this:

var result = Foo()

Then it uses result for the work. I can not modify how result works, I can only modify Foo because I pass it as parameter to the library.

If foo has something like this

funcion Foo(){
  return "Hello"
}

It works perfect. Result is Hello and it works.

The issue is that my Foo has an async call inside it. It calls a web server and then it should return the response of the server. So

funcion Foo(){
   request.get('http://server.com', function(error, response, body){
      var parsed = JSON.parse(body);
      return parsed.Hello;
   });
}

In this case when var result = Foo();, result does not contains the response of the server (because is async) and continue with an empty result.

So if I only can modify Foo what should I do?

Update: If you dont find it possible I would love to hear alternatives like what should I ask in PR for the library, or a way to force the request to be syncronous

Ricardo Polo Jaramillo
  • 12,110
  • 13
  • 58
  • 83
  • *>what should I ask in PR for the library* It would help if you described the module in more details. – lleaff Dec 29 '15 at 02:28
  • Does the library accept a promise as the return value? – Steve Hansell Dec 29 '15 at 02:32
  • @SteveHansell I dont think so... This is where the library do that: (new_buf is result and filter is Foo in my explanation) https://github.com/chazomaticus/Haraka/blob/ece98e4797d78af9aad98c0469afde50bb9ba38d/mailbody.js#L255 – Ricardo Polo Jaramillo Dec 29 '15 at 02:34

2 Answers2

1

This is how you can work with a synchronous request:

funcion Foo(){
   var request = new XMLHttpRequest();
   request.open("GET", "http://server.com", false);
   request.send();
   function handleResponse(response) {
      console.log(response);
   }
   handleResponse(request.responseText);
}

If you can only modify Foo, then modify it to send the request synchronously.

Lajos Arpad
  • 64,414
  • 37
  • 100
  • 175
  • two questions: 1. This is a Node.js app. Using sync calls will lock all execution of all users using it, or only the execution of the current user? If is only the current user I think I can accept it. 2. In Node.js not exist XMLHttpRequest so should i use this port https://github.com/driverdan/node-XMLHttpRequest or are a better way to sync request in Node.js? – Ricardo Polo Jaramillo Dec 29 '15 at 02:43
  • @RicardoPolo, 1. It should not block everyone, but it is safer to test it 2. Take a look at this library: https://github.com/coolaj86/futures – Lajos Arpad Dec 29 '15 at 03:20
  • thank you! I will go with your option. I open another question to expand what I just comment to you http://stackoverflow.com/questions/34503840/using-a-blocking-long-sync-operation-will-pause-all-users-in-node-js :) – Ricardo Polo Jaramillo Dec 29 '15 at 03:34
0

What you're trying to do is impossible per se, once code is asynchronous, it can't be used as you would synchronous code. That's why callback hell is a thing.

You could try to analyze the module internals and monkey patch it, but that may not be possible depending on what exports the module exposes.

lleaff
  • 4,249
  • 17
  • 23
  • 1
    In this case, the solution is to modify Foo to send the request synchronously. Not a nice thing to do, but that is the solution, since the code using Foo expects Foo to work synchronously. – Lajos Arpad Dec 29 '15 at 02:33
  • You are completely right, I totally forgot XMLHttpRequest had that option. – lleaff Dec 29 '15 at 02:42