node.js 异步
PS: Did you get disappointed when the code you are writing in Node was not giving you expected results or when you get different outputs than the ones you would get by implementing the same logic in a different language. Well, Node runs on asynchronous environment and I will show you how to make some of those codes run synchronously.
PS:当您在Node上编写的代码没有提供预期的结果时,或者当您获得的输出与通过使用不同语言实现相同逻辑所获得的输出不同时,您是否感到失望? 好吧,Node在异步环境上运行,我将向您展示如何使其中一些代码同步运行。
Asynchronous nature of Node is one of its performance boosters but this asynchronous behavior can sometimes be a performance issue too.
Node的异步特性是其性能增强器之一,但是这种异步行为有时也可能是性能问题。
Let’s say you want to make an asynchronous call to API and you want to do it in some specific order. You might have an ordered array to pull the data from API or you might want to store the API response in a specific order. In those cases, using built in array methods throw an unexpected result.
假设您要对API进行异步调用,并且要按特定的顺序进行。 您可能有一个有序的数组以从API中提取数据,或者您可能想以特定顺序存储API响应。 在那些情况下,使用内置的数组方法会引发意外的结果。
Let me show you an example.
让我给你看一个例子。
I will be using the http://jsonplaceholder.typicode.com/posts as a sample and I will be pulling data using a popular library called ‘axios’.
我将使用http://jsonplaceholder.typicode.com/posts作为示例,并将使用一个流行的名为“ axios”的库提取数据。
So you want to make an API call to get the posts from 1 to 10. This is the asynchronous function to pull that data from API.
因此,您想进行API调用以将帖子从1提取到10。这是异步函数,用于从API提取数据。
进行API调用的函数 (Function to make an API call)
const axios = require("axios");
const URL = "<https://jsonplaceholder.typicode.com/posts>";
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const fetchPosts = async (number) => {
try {
const data = await axios.get(`${URL}/${number}`);
return data;
} catch (error) {
console.log(error);
}
};
This function takes the post number if (provided), makes a request to the API and returns data if there is no error.
如果(提供),此函数将获取帖子编号,如果没有错误,则向API发出请求并返回数据。
Asynchronous functions are commonly used to pull data from API because since you are pulling that data from an outside provider, you have to wait until that response received and only after you receive that response, you can get started working with that data.
异步函数通常用于从API中提取数据,因为既然您是从外部提供程序中提取数据,则必须等到收到该响应为止,并且只有在收到该响应之后,您才能开始使用该数据。
So in order to get the data for posts from 1 to 10, we could write another function. One of the options that comes to mind to perform this operation is the Array.forEach().
因此,为了获取从1到10的帖子数据,我们可以编写另一个函数。 想到执行此操作的选项之一是Array.forEach() 。
数组迭代的异步函数调用 (Array iterated async function calls)
const getPostsAsync = () => {
numbers.forEach(async (number) => {
const post = await fetchPosts(number);
console.log( `Asynchronous ${post.data.id} is fetched for ${number}`);
});
console.log("Start Async");
};
getPostsAsync();
After running those functions together like this, it is the output that I get.
像这样一起运行这些功能之后,就是我得到的输出。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/be2ea11b9c1a5b1f4d9d874b5f51c375.png)
As you can see, the outputs order does not match with the order in the array. In fact, even the output from the console.log() function is printed on the top rather than on the bottom.
如您所见,输出顺序与数组中的顺序不匹配。 实际上,即使console.log()函数的输出也打印在顶部而不是底部。
So why is this happening and how we can fix this?
那么为什么会发生这种情况以及我们如何解决呢?
First of all , this is happening because of the unblocking nature of Node.js. When we run the getPostsAsync() function, it fires all those functions inside and since asynchronous requests to the API takes some time, it consoles the response from console.log() first and after that which ever response is received will be printed to the console.
首先,这是由于Node.js的无阻塞性而发生的。 当我们运行getPostsAsync()函数时,它将触发内部的所有这些函数,并且由于对API的异步请求需要一些时间,因此它将首先控制台console.log()的响应,然后将接收到的所有响应打印到安慰。
Second of all, to avoid this issue, we can use a couple of other methods. One of them is the typical for loop. ‘For loop’ waits for the first iteration to finish before proceeding to the next task.
第二,为避免此问题,我们可以使用其他两种方法。 其中之一是典型的for循环。 “ For循环”等待第一个迭代完成,然后再继续执行下一个任务。
const getPostsSync = async () => {
for (const number of numbers) {
const post = await fetchPosts(number);
console.log(`Synchronous ${post.data.id} is fetched for ${number}`);
}
};
getPostsSync();
We get the output below.
我们得到下面的输出。
![Image for post](https://i-blog.csdnimg.cn/blog_migrate/4258ae9b5919604473d7902d688f234f.png)
We get the same ordered result using the while loops too.
我们也使用while循环获得相同的有序结果。
const getPostsWhile = async () => {
while (numbers.length > 0) {
const number = numbers.shift();
const post = await fetchPosts(number);
console.log(`While ${post.data.id} is fetched for ${number}`);
}
};
Using those traditional loops not only returns the data in order but they also return the response faster than Array.forEach() method. So this is how we can run array iterations in Node synchronously.
使用这些传统循环不仅比顺序返回数据,而且比Array.forEach()方法返回响应的速度更快。 因此,这就是我们可以在Node中同步运行数组迭代的方式。
异步功能的优点 (Advantages of Asynchronous functions)
Another point in case, even if it is a drawback in this case, this asynchronous nature is one of the performance boosters in Node.js because of the fact that it allows you to perform other tasks while waiting for the response from API. Other languages such as Python waits until the response is received and only after that, it proceeds to perform the next task. It is not a good feature because CPU is left idle while waiting for the response, thus wasting time. Node avoids waiting for the response and keeps proceeding for next tasks.
另一点是,即使在这种情况下是一个缺点,这种异步性质也是Node.js中性能的增强器之一,因为它允许您在等待来自API的响应的同时执行其他任务。 其他语言,例如Python,则等待直到收到响应,然后才继续执行下一个任务。 这不是一个好功能,因为CPU在等待响应时处于空闲状态,从而浪费了时间。 Node避免等待响应,并继续进行下一个任务。
Thanks for reading and I hope it helps you to better understand array iterations in Node.js
感谢您的阅读,我希望它可以帮助您更好地了解Node.js中的数组迭代
node.js 异步