-2

Lets say I have an synchronous function for example:

var sum = function(x,y){
  return x+y
}

I want to call this function in asynchronously. How is that possible? Is the function below be considered an asynchronous function? If this is an asynchronous function then I second function's log should be logged before the first one? I know this is a very simple example which may not be an ideal case for async function. But I just wanted to get this fundamental clear.

function(a, b, c, d, e, f, function(){
  console.log(result);
})
{
   result = sum(a, b);
   result = sum(result, c);
   result = sum(result, d);
   result = sum(result, e);
   result = sum(result, f);
   return
)};


function(a, b, function(){
  console.log(result);
})
{
   result = sum(a, b);
   return
)};

Please help me. If this is not correct then please help me in as to How it should be written?

Saransh Mohapatra
  • 9,430
  • 10
  • 39
  • 50
  • You seem to not understand callbacks and asynchronous programming. You don't have anything that is asynchronous in your code. – Lee Taylor Jul 14 '13 at 14:14
  • I see this is tagged node.js, so I'll point you to this thread: http://stackoverflow.com/questions/5786016/how-do-i-make-this-js-function-asynchronous which addresses some of, if not most of, your questions. – Pete Scott Jul 14 '13 at 14:14
  • That code doesn't parse (you're using a function expression where an argument name is expected in both of the outer-level functions you define, and there are some paren/brace mis-matches). – T.J. Crowder Jul 14 '13 at 14:30

4 Answers4

3

From your comment on Quentin's answer

How to create a function which has some manipulation inside it which is a normal synchronous function but the overall flow doesn't wait for this function to complete rather moves to the next function.

JavaScript, the language, doesn't have a feature to do that. So you look to the environment in which it's running to see if the environment has that feature.

NodeJS does. In fact, it has several of them: setTimeout (which is a bit like what browsers give you), setImmediate, and process.nextTick. For your use case, setImmediate is probably the best choice, but see this question and its answers for more on that. setImmediate looks like this:

setImmediate(functionToCall);

(It's a global, you don't have to require anything.)

That does exactly what your title asks for: An asynchronous call to a synchronous function.


From your comment below:

I just need to create an async function inside which I call a normal synchronous function. When I mean asynchronous function I mean that when I call this function it doesn't obstruct the flow and the flow goes to the next function and this function can do something(like logging) after completion

That's not quite the same thing your question asks. :-)

First off, there are no asynchronous functions (in JavaScript). When you call a function in JavaScript, that function is executed synchronously. So that means you have two choices:

  1. The calling code can use setImmediate to tell Node to call the function asynchronously, or

  2. The function can do that for itself, probably using a nested function.

Here's #1:

function foo() {
    console.log("A");
    setImmediate(bar);
    console.log("B");
}
function bar() {
    console.log("C");
}
foo();

which outputs:

A
B
C

Here's #2:

function foo() {
    console.log("A");
    bar("C");
    console.log("B");
}
function bar(arg) {

    setImmediate(run);

    function run() {
        console.log(arg);
    }
}
foo();

...which also outputs

A
B
C

Note how "C" was passed as an argument to bar. bar does nothing but schedule the callback to its nested function run. run uses the argument.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • No I don't need to schedule it. I just need to create an async function inside which I call a normal synchronous function. When I mean asynchronous function I mean that when I call this function it doesn't obstruct the flow and the flow goes to the next function and this function can do something(like logging) after completion – Saransh Mohapatra Jul 14 '13 at 14:35
  • Same way means which way?? I didn't understand which way you were meaning. – Saransh Mohapatra Jul 14 '13 at 14:37
  • Please edit your answer with the example. That would be much better in understanding. – Saransh Mohapatra Jul 14 '13 at 14:38
  • Thanks. Just need one more help. If I use a module to achieve this suppose lets say async. And run two functions in async.parallel, then can I use a normal synchronous function inside these two function and after that call the callback that they mention? – Saransh Mohapatra Jul 14 '13 at 17:57
  • @SaranshMohapatra: If I'm understanding the question, yes, you can. But note that the functions won't really run in parallel unless they're doing I/O. Node's standard container is single-threaded. – T.J. Crowder Jul 14 '13 at 17:59
  • Yeah they will be doing I/O (i.e database queries and image-resizing and all). Functions will be having queries run inside them and according to the query result return something. Will that work? And just for sake of knowledge if I don't do any I/O rather any normal function with say calculation then won't they run in parallel? Is there any way to so? – Saransh Mohapatra Jul 14 '13 at 18:06
  • @SaranshMohapatra: As far as I'm aware, the I/O stuff should work. If you weren't doing I/O and handling of to async I/O completion callbacks, then no, the functions won't really run in parallel because again, Node's standard container is **single-threaded**. It can only actually do one thing at a time. So the idea with Node is to keep the size of the things you do really small, so they can be woven together. If you want truly parallel things, you can use child processes. – T.J. Crowder Jul 14 '13 at 18:37
  • Yeah but don't modules like async already use child process to achieve this effect? I think so that they do. – Saransh Mohapatra Jul 14 '13 at 18:54
  • @SaranshMohapatra: If you're talking about a specific module, it doens't happen to be one I know. Again: I haven't done much Node dev. I know a lot about JavaScript, and a *bit* about Node. – T.J. Crowder Jul 14 '13 at 18:57
0

How is that possible?

It isn't. Everything it does is a synchronous operation.

You use asynchronous code when dealing with things which are intrinsically asynchronous. This is limited, in JS, almost entirely to event handling.

Is the function below be considered an asynchronous function?

No. It has a callback, but everything it does is synchronous.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Than how would I implement something like this? – Saransh Mohapatra Jul 14 '13 at 14:21
  • You wouldn't, because it makes no sense to do so. – Quentin Jul 14 '13 at 14:22
  • What doesn't make sense? Basically what I want to know is how to create an async function inside which I am calling a normal synchronous function which returns something. – Saransh Mohapatra Jul 14 '13 at 14:27
  • It doesn't make sense because there is nothing to wait for. There's no network request. There's no user interaction. – Quentin Jul 14 '13 at 14:27
  • ok. I understood your point but what I am trying to ask is How to create a function which has some manipulation inside it which is a normal synchronous function but the overall flow doesn't wait for this function to complete rather moves to the next function. – Saransh Mohapatra Jul 14 '13 at 14:31
0

I'm not completely sure that I understand what you need, but I believe that what you're looking for is to create concurrent function calls, which means you probably need to run a potentially computationally intensive code, and you don't want it to block other code from executing while this computation runs. Node.js is usually used in a single-threaded process, which means that only a single piece of code can run at a given time, but there are still some ways to do it.

One way to do it, as stated in @T.J. Crowder 's answer, is to queue your function call with process.nextTick so it'll run on the next cycle of the event-loop. This can help break down intensive computation into iterations and that each iteration will be queued to run on the next event-loop cycle after the last one. This can help in some cases, but not always you can break down computations into iterations that run async from each other. If you're looking for a more detailed explanation into how Javascript runs asynchronously, I suggest reading this book.

There are at least two other ways (that I know of) to achieve some sort of concurrency with Node.js- Workers/Threads, and child processes. Child processes in short are just another Node.js process that is run by your main application. You can use the native *child_process* module of Node.js to run and manage your child processes if you want to go this way. Look at the official docs for more info.

The third way to do it is to use Workers in a very similar manner to how Web Workers are used in the browser. A Worker is a snippet of code that is run in a different OS thread than your main application. To me it seems that this is the easiest way to achieve concurrency, although some will argue it is not the most robust way of doing it, and that creating child processes is better.

There a very good explanation of how Workers function on MDN. To use Workers in Node.js you will need an external module such as webworker-threads.

Here's a code sample created from your sample with a snippet from their documentation:

var Worker = require('webworker-threads').Worker;

var worker = new Worker(function(){
    onmessage = function(event) {
        result = sum(event.data.a, event.data.b);
        result = sum(result, event.data.c);
        result = sum(result, event.data.d);
        result = sum(result, event.data.e);
        result = sum(result, event.data.f);
        postMessage(result);
        self.close();
    };
});
worker.onmessage = function(event) {
    console.log("The result is: " + event.data);
};
worker.postMessage({a: 1, b: 2, c: 3, d: 4, e: 5, f: 6});

// Do some other stuff that will happen while your Worker runs...

With all that said, most people will try to avoid running concurrent code in Node.js. Javascript's async nature makes it easy to write simple and concise back-end code, and usually you would want to keep it that way by not trying to introduce concurrency into your application, unless it is absolutely necessary.

Naor Biton
  • 952
  • 9
  • 14
  • Why so negative? :) I just described another way concurrency can be achieved. If any of this is wrong or misleading, I'll be happy to be corrected. – Naor Biton Jul 16 '13 at 08:05
-2

In Javascript (leaving node aside for a moment) An asynchronous function should be called via setTimeout(). SetTimeout will not block the script execution while waiting:

function someThingThatTakesAWhile() { 
    for (var i = 0; i < someVeryLargeNumber; i++) {
        //...
    };
}
setTimeout(function () {
    someThingThatTakesAWhile();
}, 0);

(haven't tested that, please forgive typos, &c)

But if you're wanting to do this in node, I don't think this is what you really want.

Pete Scott
  • 1,516
  • 10
  • 10
  • 1
    I want to do it in node – Saransh Mohapatra Jul 14 '13 at 14:27
  • P.S. You ability to "return" the value will cease to exist. You'll need to call another function (a callback) to handle the result of your "asynchronous" function. – Pete Scott Jul 14 '13 at 14:27
  • Then please see my comment above on your question pointing you to a near-duplicate stackoverflow question. – Pete Scott Jul 14 '13 at 14:28
  • 1
    *"In Javascript (leaving node aside for a moment)"* `setTimeout` is a feature of the browser environment, not JavaScript, and doesn't exist in non-browser JavaScript environments. – T.J. Crowder Jul 14 '13 at 14:31
  • @T.J. Crowder, Ah. That never even occurred to me. Thanks for the clarification. – Pete Scott Jul 14 '13 at 14:33
  • 1
    @PeteScott: *(Quoting myself)* *"...and doesn't exist in non-browser JavaScript environments."* **unless they provide it**, which in fact, [**Node does now**](http://nodejs.org/api/all.html#all_settimeout_callback_delay_arg). :-) – T.J. Crowder Jul 14 '13 at 17:04
  • @T.J.Crowder, Good to know. process.nextTick() would obviously still be the better solution (for immediate execution). Is setTimeout() the only option for delayed execution? (feel free to convert to chat if this is too far off-topic). – Pete Scott Jul 14 '13 at 17:45
  • @PeteScott: I don't know (well, I mean, there's also a `setInterval` that both browsers and Node provide), I haven't done that much Node stuff. Just haven't had a relevant project. – T.J. Crowder Jul 14 '13 at 17:49