0% found this document useful (0 votes)
5 views29 pages

Bài 27 Async Javascript

Asynchronous programming allows tasks to be interleaved, enabling a program to continue executing while waiting for I/O-bound operations to complete, thus improving performance. Key concepts include non-blocking operations, concurrency, and the event loop, which manages multiple tasks efficiently. Promises and the 'await' keyword in JavaScript further simplify handling asynchronous operations, allowing for more readable code without falling into callback hell.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views29 pages

Bài 27 Async Javascript

Asynchronous programming allows tasks to be interleaved, enabling a program to continue executing while waiting for I/O-bound operations to complete, thus improving performance. Key concepts include non-blocking operations, concurrency, and the event loop, which manages multiple tasks efficiently. Promises and the 'await' keyword in JavaScript further simplify handling asynchronous operations, allowing for more readable code without falling into callback hell.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

ASYNC JAVASCRIPT

In asynchronous programming, tasks are not necessarily done at the exact same time, but rather,
tasks are interleaved in such a way that the program can continue doing useful work while
waiting for other tasks to complete. This approach can make your code run faster in specific
contexts, especially when dealing with I/O-bound operations. Here's how it works and why it can
improve performance:
Key Concepts of Asynchronous Programming:

1. Non-blocking Operations:
o Asynchronous code allows the program to start a potentially slow operation (like
reading from a file, waiting for a network response, or querying a database) and
then move on to other tasks without waiting for that operation to complete.
2. Concurrency:
o While one task is waiting for an I/O operation to complete, another task can run.
This is particularly useful for I/O-bound tasks where the CPU would otherwise be
idle while waiting for the I/O operation to finish.
3. Event Loop:
o In an asynchronous system, an event loop takes care of managing multiple tasks.
It repeatedly checks for completed tasks and schedules new ones, ensuring that
the program efficiently utilizes available resources.

Example Scenario:

Consider a web server that needs to handle multiple incoming HTTP requests:

 Synchronous Approach:
o The server handles one request at a time. Each request is processed sequentially,
and if one request involves a slow operation (e.g., database query), all other
requests have to wait.
 Asynchronous Approach:
o The server can start handling a request, and if it needs to wait (e.g., for a database
query), it can switch to handling another request in the meantime. This allows the
server to serve many requests concurrently without being blocked by slow
operations.

Why It Can Be Faster:

1. Better Resource Utilization:


o In synchronous programming, the CPU can be idle while waiting for I/O
operations. Asynchronous programming keeps the CPU busy by allowing it to
work on other tasks during this waiting time.
2. Reduced Idle Time:
o Asynchronous programming minimizes idle time by quickly switching between
tasks, making the overall execution more efficient.
3. Parallel I/O Operations:
o Asynchronous programming allows multiple I/O operations to be in progress
simultaneously. While one operation waits for data, another can proceed, thus
speeding up the overall execution.

Asynchronous programming can make your code run faster by efficiently managing I/O-bound
tasks and keeping the CPU busy. While tasks are not done at the exact same time, the
interleaving of tasks ensures better utilization of resources and reduced idle time, leading to
improved performance in scenarios involving I/O operations.

4o
i kinda get it now , so for example we have two tasks , task 1 and task 2. Task 2 needs the data
from the database so in async programming, task 1 can be done when the data is being sent so
that task 2 can get its job done. Therefore the code can be faster, is that correct?
ChatGPT

Yes, you’ve got it right! In asynchronous programming, while Task 2 is waiting for the data to
be retrieved from the database (an I/O-bound operation), Task 1 can proceed with its execution.
This allows the program to make better use of its time and resources, ultimately making the
overall execution faster.

Here’s a more detailed breakdown of how this works:

1. Task 2 Initiates a Database Query:


o Task 2 starts a database query and awaits the result.
o Instead of blocking and doing nothing while waiting for the database response,
the program switches to other tasks that can be performed in the meantime.
2. Task 1 Executes While Waiting:
o While Task 2 is waiting for the database to respond, Task 1 can execute.
o This could be any kind of work, such as processing data, handling user input, or
performing calculations.
3. Database Responds:
o Once the database query completes, Task 2 can resume its execution with the
retrieved data.
o At this point, Task 1 might still be running, or it might have already completed.

This interleaving of tasks allows the program to keep working on something productive, rather
than sitting idle while waiting for I/O operations to complete.

Event Loop and Callback Queue

1. Call Stack: The call stack is where JavaScript keeps track of what function is currently
being executed and what functions are called from within that function.
2. Web APIs: When asynchronous operations (like setTimeout, HTTP requests via
XMLHttpRequest or fetch, or DOM events) are called, they are handed off to the
browser's Web APIs (or [Link]'s equivalent APIs) and not executed in the main thread
directly.
3. Task Queue (Callback Queue): Once these asynchronous operations complete (e.g., the
HTTP request returns, the timer finishes, or an event occurs), the callbacks associated
with these operations are pushed into the task queue.
4. Event Loop: The event loop continuously checks the call stack to see if it’s empty. If the
call stack is empty, the event loop takes the first callback from the task queue and pushes
it onto the call stack, effectively allowing asynchronous callbacks to run.
Certainly! Let's break down how asynchronous functions can send a request
and handle other tasks while awaiting a response, within the context of the
Event Loop and Callback Queue.

Event Loop and Callback Queue Basics


In languages like JavaScript ([Link]) or Python (with asyncio), asynchronous
operations are managed by an event loop:

Event Loop:

The event loop is responsible for managing and executing asynchronous


tasks.

It continuously checks the state of asynchronous operations and schedules


tasks for execution.

Callback Queue (or Task Queue):

Asynchronous functions often use callbacks or awaitables (like Promises in


JavaScript or coroutines in Python) to signal completion of tasks.

When an asynchronous operation completes, its callback or continuation is


placed in the callback queue.

Example Scenario

Let’s consider an example where we have two tasks:

Task 1: Send a network request.

Task 2: Process some data.

Asynchronous Function Execution Flow

Initiating Task 1 (Send Network Request):

The asynchronous function for Task 1 initiates a network request (e.g., an


HTTP request).

Instead of blocking and waiting for the response, it registers a callback (or
uses await in Python) and returns control to the event loop.

Execution Continues with Task 2:


Task 2, which processes data or performs another task, can start executing
immediately after Task 1 yields control back to the event loop.

This happens because Task 2 does not depend on the completion of Task 1.

Awaiting Response and Callback Execution:

Meanwhile, the event loop is continuously monitoring the status of the


network request initiated by Task 1.

When the network request completes, its callback (or the continuation of the
coroutine in Python) is placed in the callback queue.

Callback Queue Handling:

The event loop dequeues the callback from the callback queue and executes
it. This callback resumes execution of Task 1, handling the response data or
performing further actions based on the network response.

Đó là các lợi ích của async , quay trở lại sync ta sẽ có một vài vấn đề , điển
hình là callback hell
Demo: fake request using callback hell
Promise trong javascript

Làm Việc Với Promises Trong


JavaScript
Chào các bạn! Ở bài học trước chúng ta đã tìm hiểu về callback trong
JavaScript. Tiếp tục với series hôm nay chúng ta sẽ cùng nhau làm rõ các vấn
đề về promises thông qua các ví dụ thực tiễn.

Promises trong JavaScript là gì?


Promise là một cơ trong JavaScript giúp bạn thực thi các tác vụ bất đồng bộ
mà không rơi vào tình trạng có quá nhiều các callback lồng vào nhau gây
tình trạng callback hell hay pyramid of doom. Thực tế promises là 1 special
JavaScript object thể hiện cho sự hoàn thành hoặc thất bại của một tiến trình
bất đồng bộ.

Cách sử dụng promises trong JavaScript


Cú pháp:

let promise = new Promise(function(resolve, reject) {


});
Khi promise thực thi hoàn thành công việc, nó sẽ gọi một trong 2 hàm là
resolve(value) và reject(error). Giả sử trên kia là một lời cầu hôn của chàng
trai dành cho cô gái, ban đầu cô gái hẳn sẽ ngại ngùng còn ngập ngừng
(Pending), nhưng sau đó chắc chắn cô gái sẽ đồng ý hoặc từ chối bạn. Hai đối
số trên cũng giống như lời tỏ tình vậy. Nếu đồng ý resolve(value) thì status
sẽ là "fulfilled", và result chính là value. Còn cô gái từ chối reject(error) lúc
này status sẽ là "rejected" và result chình là error.

Để tiếp tục câu chuyện tình yêu ban nãy, bây giờ chúng ta sẽ khởi tạo
một promises và thực thi thông qua setTimeout .

let promise = new Promise(function(resolve, reject) {


// the function is executed automatically when the
promise is constructed

// after 1 second signal that the job is done with the


result "done"
setTimeout(() => resolve("done"), 1000);
});
Đây chính là trường hợp chàng trai đã đưa ra lời tỏ tình thành công với
cô gái, đó hẳn một tin vui. Tuy nhiên cô gái vẫn chưa đưa ra câu trả lời.
Ở đoạn code trên, sau một giây “xử lý”, trình thực thi sẽ
gọi resolve("done") để đưa ra kết quả. Điều này thay đổi trạng thái
của promise đối tượng:

Còn nếu chàng trai cũng ngại ngùng nói không nên lời cầu hôn thì sao.
Đó chắc chắn là thất bại rồi:
let promise = new Promise(function(resolve, reject) {
// after 1 second signal that the job is finished with an
error
setTimeout(() => reject(new Error("Whoops!")), 1000);
});
Tóm lại, người thực thi nên thực hiện một công việc sau đó gọi resolve
hoặc reject để thay đổi trạng thái của promise tương ứng. Một promise
được giải quyết resolve hoặc bị từ chối reject được gọi là "settled" ,
nó trái ngược với promise ban đầu "Pending".

then
Giả sử anh chàng ban nãy đã đưa ra lời tỏ tình thành công với cô gái.
Vậy làm sao để chúng ta biết cô gái đó đồng ý hay không. Lúc này giải
pháp được đưa ra là sử dụng then . Nó có cú pháp cơ bản như sau:
 Đối số đầu tiên của .then là một hàm chạy khi promise được giải
quyết và nhận kết quả.
 Đối số thứ hai của .then là một hàm chạy khi promise bị từ chối
và nhận được lỗi.

Ví dụ: đây là một promise được giải quyết thành công:

let promise = new Promise(function(resolve, reject) {


setTimeout(() => resolve("done!"), 1000);
});

// resolve runs the first function in .then


[Link](
result => alert(result), // shows "done!" after 1 second
error => alert(error) // doesn't run
);

Còn đây là trường hợp bị từ chối:


let promise = new Promise(function(resolve, reject) {
setTimeout(() => reject(new Error("Whoops!")), 1000);
});

// reject runs the second function in .then


[Link](
result => alert(result), // doesn't run
error => alert(error) // shows "Error: Whoops!" after 1
second
);
Còn nếu bạn muốn cô gái đồng ý luôn thì:
let promise = new Promise(resolve => {
setTimeout(() => resolve("done!"), 1000);
});

[Link](alert); // shows "done!" after 1 second


Đây là trường hợp bạn chỉ quan tâm đến việc hoàn thành thành công,
bạn có thể cung cấp một đối số hàm cho .then

Một promise ví dụ

Nếu resolved =>


Có thể viết lại thành :

(cái này đỡ phải nest)


Trường hợp async lỗi
awaitis usually used to unwrap promises by passing a Promise as
the expression. Using await pauses the execution of its
surrounding async function until the promise is settled (that is, fulfilled or
rejected). When execution resumes, the value of the await expression
becomes that of the fulfilled promise.
The await keyword in JavaScript is used inside an async function to pause the
execution of the function until a Promise is resolved or rejected. It simplifies
working with asynchronous code by allowing you to write it in a more
synchronous, readable manner.

Here's how await works in the context of an async function:

Key Points:

1. Pauses Execution Until Promise Resolves or Rejects: When await


is used, it halts the execution of the code at that point until the
promise is either fulfilled (resolved) or rejected.

2. Only Usable in async Functions: You can only use await inside
functions marked as async. If you try to use it outside of such a
function, it will result in a syntax error.

3. Returns the Resolved Value: If the promise is resolved, await


returns the value that the promise resolves with. If the promise is
rejected, it throws the error, which you can handle using a try...catch
block.

Example 1: Using await to Wait for a Promise

javascript

Copy code

async function fetchData() {


let promise = new Promise((resolve) => {

setTimeout(() => resolve('Data loaded!'), 2000);

});

let result = await promise; // Pauses here until the promise resolves

[Link](result); // Logs: "Data loaded!" after 2 seconds

fetchData();

You might also like