综合技术

Asynchronous call to synchronous function

微信扫一扫,分享到朋友圈

Asynchronous call to synchronous function
0

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?

Problem courtesy of: Saransh Mohapatra

Solution

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.

Solution courtesy of: T.J. Crowder

Discussion

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.

Discussion courtesy of: Pete Scott

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.

Discussion courtesy of: Naor Biton

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.

Discussion courtesy of: Quentin

This recipe can be found in it’s original form on Stack Over Flow
.

阅读原文...


微信扫一扫,分享到朋友圈

Asynchronous call to synchronous function
0

Node.js Recipes

Using BufferedReader in java to read an input line before reading string lines from a text file

上一篇

关于2019 前端技术规划该包含什么?

下一篇

评论已经被关闭。

插入图片

热门分类

往期推荐

Asynchronous call to synchronous function

长按储存图像,分享给朋友