[英]Using Promises and Async/Await in JavaScript
我在 JavaScript 中阅读了一些关于 Promises 和async
/ await
的文章来理解它的观点,但还没有完全理解它; 所以,我会在这里解释一个例子,希望你帮助我理解这个机制。 以下代码在 NestJS 中。
这是我的auth.service.ts
:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { UserRepository } from './user.repository';
@Injectable()
export class AuthService {
constructor(
@InjectRepository(UserRepository)
private userRepository: UserRepository
) {}
createUser(): void {
this.userRepository.createUser();
console.log('Here I want to do some other works simultaneously while this.userRepository.createUser() is also processing');
}
}
这是我的user.repository.ts
:
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';
@EntityRepository(User)
export class UserRepository extends Repository<User> {
async createUser(): Promise<void> {
await this.makeUser();
}
async makeUser(): Promise<void> {
return new Promise((resolve, reject) => {
// Simulating making a user which will take some time
let x = 1;
for (let i = 0; i < 1000000000; i++) {
x++;
}
console.log('User Created');
resolve();
});
}
}
根据上面的代码和到目前为止我所学到的,我期望的是console.log('Here I want to do some other works simultaneously...')
行在this.userRepository.createUser()
,但这不会发生,我首先记录了"User Created"
,然后我得到"Here I want to do some other works simultaneously..."
。
我哪里错了?
问题是您的makeUser()
function 实际上并不是异步的。 仅仅因为它返回 promise 并不意味着它执行的工作不会阻塞不等待其完成的代码路径。 JavaScript 仍然是单线程的,在for
循环完成之前,没有其他代码能够执行。
一个更合理的模拟实现可能如下所示:
async makeUser(): Promise<void> {
return new Promise((resolve, reject) => {
// Simulating making a user which will take some time
setTimeout(() => {
console.log('User Created');
resolve();
}, 1000);
});
}
请注意, setTimeout()
是真正异步 function 的示例:它安排 function 稍后调用,而不会阻塞线程。 另请注意,由于 JavaScript 是单线程的,因此setTimeout()
调度的回调 function 将在所有其他代码路径执行完毕后才会执行,因此这是双向的,以下不会导致两个同时执行的代码路径:
setTimeout(() => { console.log('scheduled'); }, 50); let later = Date.now() + 100; while (later > Date.now()) {} console.log('done');
在这种情况下, scheduled
永远不会在done
之前出现,它总是会在之后打印。
使用Workers在 JavaScript 中可以实现多线程。
但是,由于 JavaScript 是单线程的,因此诸如 Workers 之类的东西是由您运行 JavaScript 的环境(NodeJS 或浏览器)提供的。制作 http 是很好的例子。 它们不是 JavaScript 本身的一部分,而是由浏览器或 NodeJS 实现。
有关异步工作的示例,请在一些JS 操场上运行以下代码段:
(async function () {
function makeRequest() {
return fetch('https://jsonplaceholder.typicode.com/todos/1').then(response => response.json()).then(json => console.log("Http request complete", json))
}
const promise = makeRequest()
console.log('Here I want to do work while the http request is made')
await promise
console.log("Here I want to continue after http request is complete")
})();
我哪里错了?
JavaScript 是单线程的,所以任何时候只能运行一段代码。
有一些例外,例如 HTTP 请求(这些请求被移交给线程)。
异步并不意味着“并行”。
同步执行是有序的:一件接一件的事情发生:
异步执行没有顺序(因此是异步的):
您可能想知道“在您的异步示例中,Do Task 1 和 Do Task 2 是并行执行的”。 这不是真的,异步性与并行性无关,它与“无序”执行有关。
异步性背后的力量在于,如果正确实施,允许多个代码段“乱序”运行,给人的印象是它们是并行运行的。 *
*这并不是说异步代码不允许并行。 实际上是异步代码允许并行处理发生的情况,因为结果是在它准备好时处理的。 当然,如果你只有一个线程,那么异步根本不会给你带来任何真正的好处。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.