问题描述
我是NodeJS的新手,我发现使用异步函数有点困难。我试图找出这里的好处。以下是我对异步函数的理解。
I am new to NodeJS and I am finding it slightly hard to work with asynchronous functions. I am trying to figure out the benefits here. Below are my understandings on Asynchronous functions.
请您在下面验证我的每个谅解吗?
- 当要执行独立操作(来自主程序流程)时,异步函数很好用。当主程序非常需要来自异步函数的数据/响应或者各种独立的异步函数互连时,使用异步函数并不理想。
- 这不好依赖于主程序流中异步函数输出的结果。因为Async总是在主流之后执行。因此,如果您需要在主流中执行某些功能,那么将其定义为Synchronous,而不是异步是很好的。
- 当调用Independent async函数时,通常会调用它后续操作(异步功能),使用promises或回调。
- 我仍然可以在异步功能中调用同步功能。但是如果我从同步函数调用异步函数,程序可能无法正常工作,因为异步函数只会在最后执行?
- Asynchronous functions are good to use when an independent operation (from the main program flow) to be executed. It is not ideal to use asynchronous functions when the data/response from the asynchronous function is very much required by the main program or when the various independent asynchronous functions are interconnected.
- It is not good to depend on the result of the output of the async function in the main program flow. Because Async always executes after the main flow. So if you need some functions to be executed in the main flow, its good to define it as Synchronous, not asynchronous.
- When Independent async functions are called, it's a common practice to call the subsequent operation(async function), using promises or callbacks.
- I still can call a sync function within an Async function. But if I call an async function from a sync function the program may not work as expected since the async function will be executed only at the last?
推荐答案
好的,让我们一块一块地看一下。作为基础,请记住Node.js是单线程进程,如果它需要执行阻塞进程
,例如读取文件(创建)一个事件指针,读取文件句柄,设置文件路径,设置打开模式等等。)最好使用在同一页面或线程s /池的单独线程上执行的异步函数。
Alright, let's look into it piece by piece. Just as a base, remember that Node.js is a single threaded process and if it needs to execute blocking processes
such as reading a file (create an event pointer, read the file handle, set file path, set open mode, etc.) it's better to use async functions which execute on a separate thread of the same page or thread s/pool.
对于初学者,我们不会将程序文件称为主程序
因为Node.js世界中没有子程序(我不谈论模块等)。
For starters, we will not refer to the program file as the main program
since there are no sub-programs in the Node.js world (I am not talking about modules and the likes).
现在,当你说在需要输出时不应该使用任何异步功能时,你实际上是对的。我们来看下面的例子:
Now, you are actually right on the money when you say that you shouldn't use any async functions when there is an immediate need of the output. Let's take the following example:
...
const data = readFile( 'fileName', ( data, output ) => {
...
} );
console.log( data ); // this might be null or undefined
在上面的例子中,我们不会使用异步函数(在传统意义)。但是,使用ES6及以上版本,我们可以获得可爱的范例:
In the above case, we will not use async function (in the traditional sense). However, with ES6 and above, we get the lovely async/await
paradigm:
const data = await readFile( 'filename' );
await
使调用伪同步:它的行为类似于 async
函数,但是会有一个等待输出的暂停线程。所以,在这里,你是绝对正确的!让我们继续。
await
makes the call pseudo-sync: it behaves like an async
function, but there will be a paused thread to wait for the output. So, here, you are absolutely right! Let's move on.
在这里,你说 async
在主流之后运行。现在, 不正确。让我画一个线程评估和执行的简单图片:
Here, you say that async
operates after the main flow. Now, that is incorrect. Let me draw a simple picture of thread evaluations and execution:
说,有两个 sync
函数 A()
和 B()
,它们对应的线程是 th__A
和 th__B
,它们会是这样的:
Say, there are two sync
functions A()
and B()
, and their corresponding threads are th__A
and th__B
, they will go something like this:
th__a ---> th__b
如果按照 A()$ c的顺序触发它们$ c>然后
B()
。它等待第一次同步(或阻塞)过程的评估,然后执行第二次同步(或阻塞)过程。很明显,它不是在整个执行结束之后。
If they are fired in the order A()
then B()
. It waits for the evaluation of the first sync (or blocking) process and then executes the second one. As is evident, it is NOT after the entire execution ends.
但是,如果它们现在是异步函数,它们将并行执行。说 A()
是同步函数而 B()
是一个异步函数,具有与上面相同的线程名称,执行是这样的:
However, if they are now async functions, they will execute in parallel. Say A()
was a sync function and B()
was an async function with the same thread names as above, the execution is something like this:
th__a ----
- - th__b ->
其中 -
代表一个时钟周期 - >
表示执行结束。我们可以看到 A()
被触发,然后在新线程上触发 B()
。
Where -
represents a clock cycle and ->
represents the end of execution. We can see that A()
is fired and then, on a new thread, B()
is fired.
我想这是有道理的。现在,再次回来,如果您需要立即使用它们,然后再作为异步调用,请使用等待
。
I guess this makes sense. Now, coming back, again if you need to use them immediately while having then as async calls, use await
.
绝对。
说,我们定义一个函数 sayHello()
:
Say, we define a function sayHello()
:
const sayHello = () => {
const P = Q.defer();
// P.resolve(data);
// or if there is an exception
// P.reject(error);
return p.promise;
};
其中是优秀的承诺库。我们可以这样称呼:
where Q
is the excellent promise library. We can call it like:
sayHello.then( ( data ) => {
console.log( data ); // P.resolve(..) is working here since the promise was successful.
} ).catch( ( err ) => {
console.log( err ); // P.reject(..) is working here since there was a problem.
} );
或者你可以使用像:
Or you can use call backs like fs.readFile(...)
:
fs.readFile( 'fileName', ( e, data ) => {
if( e ) { return console.log( e ); } // error was handled
// perform subsequent functions here with data
} );
不是真的。参见第(2)点。这是关于线程的。不是静态过程。您可以在异步函数中调用同步函数,它将完美地工作。
Not really. Refer to point (2). It's about threads. Not static processes. You can very well call a sync function within an async function and it'll work perfectly.
当您执行读取文件时,假设您要将数据拆分 \ n
或新行:
When you do read file, say you want to split the data by \n
or new line:
...
if( e ) { return console.log( e ); }
const dataLines = e.split( '\n' ); // this will work brilliantly
...
我希望这能让一切变得清晰! :)
I hope this made everything clear! :)
这篇关于为什么异步通过同步功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!