<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Do Van Phuc</title>
    <description>The latest articles on Forem by Do Van Phuc (@dvphuc_175).</description>
    <link>https://forem.com/dvphuc_175</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2815354%2Fc579722b-45b9-48ec-b45e-19a77299276e.jpeg</url>
      <title>Forem: Do Van Phuc</title>
      <link>https://forem.com/dvphuc_175</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dvphuc_175"/>
    <language>en</language>
    <item>
      <title>Các kiểu HTTP Authentication</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sun, 02 Mar 2025 14:35:27 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/cac-kieu-http-authentication-3gad</link>
      <guid>https://forem.com/dvphuc_175/cac-kieu-http-authentication-3gad</guid>
      <description>&lt;p&gt;&lt;strong&gt;HTTP Authentication&lt;/strong&gt; là một cơ chế xác thực người dùng trực tiếp trong giao thức HTTP để kiểm soát quyền truy cập vào tài nguyên trên web. Nó được sử dụng khi client (trình duyệt, ứng dụng) cần chứng minh danh tính với server trước khi truy cập dữ liệu hoặc API.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Các loại HTTP Authentication phổ biến&lt;/strong&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Basic Authentication&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Basic Authentication là một phương thức xác thực đơn giản sử dụng username và password để xác minh người dùng. Nó là một phần của chuẩn HTTP và thường được sử dụng trong các API đơn giản hoặc các hệ thống không yêu cầu bảo mật quá cao.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cách hoạt động&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client gửi yêu cầu:&lt;/strong&gt;&lt;br&gt;
Khi truy cập một API hoặc tài nguyên được bảo vệ, client phải gửi yêu cầu có chứa thông tin xác thực.&lt;br&gt;
&lt;strong&gt;Mã hóa thông tin xác thực:&lt;/strong&gt;&lt;br&gt;
Username và password được ghép lại theo định dạng username:password.&lt;br&gt;
Sau đó, chuỗi này được mã hóa bằng Base64.&lt;br&gt;
Ví dụ:&lt;br&gt;
&lt;code&gt;username:password -&amp;gt; dXNlcm5hbWU6cGFzc3dvcmQ=&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gửi trong header HTTP:&lt;/strong&gt;&lt;br&gt;
Client gửi chuỗi mã hóa này trong header của request:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server kiểm tra và phản hồi:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server giải mã Base64, kiểm tra username và password.&lt;/li&gt;
&lt;li&gt;Nếu đúng, server trả về status 200 OK cùng với dữ liệu yêu cầu.&lt;/li&gt;
&lt;li&gt;Nếu sai, server trả về status 401 Unauthorized.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Ưu, nhược điểm của Basic authentication&lt;/strong&gt;&lt;br&gt;
Basic Authentication có ưu điểm là đơn giản, dễ triển khai và không cần can thiệp vào mã nguồn backend. &lt;br&gt;
Tuy nhiên, nó có nhược điểm về bảo mật, thiếu tính linh hoạt và không phù hợp cho các ứng dụng phức tạp hoặc mobile. &lt;br&gt;
Vì vậy, cần cân nhắc sử dụng phương pháp xác thực khác như JWT hoặc OAuth cho các ứng dụng yêu cầu bảo mật cao hơn và tính năng phức tạp hơn.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;JWT (JSON Web Token)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;JWT là một tiêu chuẩn mở (RFC 7519) dùng để truyền thông tin an toàn giữa các bên dưới dạng JSON. Nó thường được sử dụng để xác thực người dùng và cấp quyền truy cập trong API hoặc ứng dụng web.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Cấu trúc của JWT&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;JWT có ba phần chính, được phân tách bởi dấu chấm (.):&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Header:&lt;/strong&gt; Chứa loại token và thuật toán mã hóa (thường là HMAC hoặc RSA).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"alg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"HS256"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"typ"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"JWT"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Payload:&lt;/strong&gt; Chứa thông tin của user và các claims (quyền hạn, thời gian hết hạn,...).&lt;br&gt;
Claims là tập hợp các thông tin đại diện cho một thực thể (object) (ví dụ user_id) và một số thông tin đi kèm. Claims sẽ có dạng Key - Value. Do đó, chúng ta có thể hiểu rằng, claims ám chỉ việc yêu cầu truy xuất tài nguyên cho object tương ứng.&lt;/p&gt;

&lt;p&gt;Có ba loại claim chính:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registered claims: Là các claim được định nghĩa sẵn bởi chuẩn JWT, bao gồm "iss" (Issuer), "sub" (Subject), "exp" (Expiration Time), "nbf" (Not Before), "iat" (Issued At) và "jti" (JWT ID).&lt;/li&gt;
&lt;li&gt;Public claims: Là các claim mà có thể được sử dụng không xung đột với các standard claim, nhưng cần thống nhất với các entities sử dụng JWT.&lt;/li&gt;
&lt;li&gt;Private claims: Là các claim mà được sử dụng để chuyển thông tin giữa các bên, nhưng không được định nghĩa trong chuẩn JWT.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sub"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1234567890"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"admin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1710000000&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Signature:&lt;/strong&gt; Được tạo ra bằng cách mã hóa base64 của header và payload sử dụng thuật toán đã được chỉ định trong header bằng cách sử dụng một secret key. Signature này dùng để xác minh tính hợp lệ của token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Khi kết hợp, các phần header, payload và signature tạo thành một chuỗi token có dạng "{base64url-encoded header}.{base64url-encoded payload}.{signature}". &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ví dụ về JWT hoàn chỉnh:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNzEwMDAwMDAwfQ.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;strong&gt;Cách hoạt động của JWT&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Client gửi yêu cầu đăng nhập với username &amp;amp; password.&lt;/li&gt;
&lt;li&gt;Server kiểm tra thông tin: Nếu đúng, server tạo một JWT chứa thông tin người dùng. Trả lại JWT cho client.&lt;/li&gt;
&lt;li&gt;Client gửi JWT trong các request tiếp theo: JWT được gửi trong header HTTP: &lt;code&gt;Authorization: Bearer &amp;lt;JWT&amp;gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Server kiểm tra JWT: Nếu hợp lệ, server xác nhận người dùng và xử lý request. Nếu không hợp lệ hoặc hết hạn, trả về status 401 Unauthorized.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ưu, nhược điểm của JWT
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Ưu điểm của JWT&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Không cần lưu trữ trạng thái trên server (stateless).&lt;/li&gt;
&lt;li&gt;Nhanh và hiệu quả: Vì token chứa toàn bộ thông tin, server không cần truy vấn database mỗi lần xác thực.&lt;/li&gt;
&lt;li&gt;Có thể chứa nhiều thông tin như quyền hạn, thời gian hết hạn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Nhược điểm của JWT&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Không thể thu hồi: Nếu JWT bị rò rỉ, kẻ tấn công có thể sử dụng nó đến khi hết hạn.&lt;/li&gt;
&lt;li&gt;Kích thước lớn hơn Basic Auth do chứa nhiều thông tin.&lt;/li&gt;
&lt;li&gt;Cần bảo mật khóa bí mật: Nếu bị lộ, JWT có thể bị giả mạo.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Kết luận&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;HTTP Authentication là một cơ chế quan trọng để bảo vệ tài nguyên trên web và kiểm soát quyền truy cập của người dùng. Hai phương thức phổ biến là Basic Authentication và JWT (JSON Web Token), mỗi phương thức đều có ưu điểm và nhược điểm riêng. Bên cạnh Basic Authentication và JWT, còn có nhiều phương thức xác thực phổ biến khác như OAuth, Digest Authentication,...&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cookie</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sun, 02 Mar 2025 08:22:20 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/cookie-2fim</link>
      <guid>https://forem.com/dvphuc_175/cookie-2fim</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Cookie là những tập tin một trang web gửi đến máy người dùng và được lưu lại thông qua trình duyệt khi người dùng truy cập trang web đó. &lt;/li&gt;
&lt;li&gt;Trình duyệt có thể lưu trữ cookie, tạo cookie mới, sửa đổi cookie hiện có và gửi lại chúng cho cùng một máy chủ với các yêu cầu sau. &lt;/li&gt;
&lt;li&gt;Cookie cho phép các ứng dụng web lưu trữ một lượng dữ liệu hạn chế và ghi nhớ thông tin trạng thái; theo mặc định, giao thức HTTP là không trạng thái (không giữ lại thông tin trạng thái giữa các yêu cầu, vì vậy cookie giúp duy trì thông tin trạng thái cần thiết).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cookie được sử dụng để làm gì?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Thông thường, máy chủ sẽ sử dụng nội dung của cookie HTTP để xác định xem các yêu cầu khác nhau có đến từ cùng một trình duyệt/người dùng hay không và sau đó đưa ra phản hồi được cá nhân hoá hoặc phản hồi chung phù hợp.&lt;br&gt;
Cookie chủ yếu được sử dụng cho ba mục đích:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quản lý phiên : Trạng thái đăng nhập của người dùng, nội dung giỏ hàng hoặc bất kỳ thông tin chi tiết nào khác liên quan đến phiên của người dùng mà máy chủ cần ghi nhớ.&lt;/li&gt;
&lt;li&gt;Cá nhân hóa : Tùy chọn của người dùng như ngôn ngữ hiển thị và chủ đề UI.&lt;/li&gt;
&lt;li&gt;Theo dõi : Ghi lại và phân tích hành vi của người dùng.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cookie được truyền lên server khi nào?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Khi trình duyệt gửi các yêu cầu HTTP lên server, nó cũng gửi cookie liên quan đến server.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Các tham số chính mà máy chủ có thể thiết lập cho một cookie:&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: Tên của cookie, dùng để nhận diện cookie. Đây là tham số bắt buộc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Value&lt;/strong&gt;: Giá trị của cookie, thường là chuỗi văn bản. Đây cũng là tham số bắt buộc.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Expires&lt;/strong&gt;: Thời gian hết hạn của cookie, được định dạng dưới dạng ngày giờ. Khi hết hạn, cookie sẽ bị trình duyệt xoá. Nếu không đặt, cookie sẽ và bị xoá khi đóng trình duyệt. Ngoài ra có thể sử dụng Max-Age (tính bằng giây) để set thời gian đếm ngược.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Domain&lt;/strong&gt;: Tên miền mà cookie liên quan đến. Nếu không đặt, mặc định sẽ là tên miền của trang web đã thiết lập cookie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Path&lt;/strong&gt;: Đường dẫn mà cookie liên quan đến. Cookie sẽ được gửi lại cho máy chủ khi truy cập vào các đường dẫn khớp với giá trị này. Nếu không đặt, mặc định sẽ là đường dẫn của trang đã thiết lập cookie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secure&lt;/strong&gt;: Cookie chỉ được gửi qua kết nối HTTPS thay vì HTTP, giúp bảo mật thông tin hơn.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HttpOnly&lt;/strong&gt;: Cookie sẽ không thể truy cập được từ JavaScript thông qua document.cookie. &lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>RESTful API</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 01 Mar 2025 21:27:42 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/restful-api-39kg</link>
      <guid>https://forem.com/dvphuc_175/restful-api-39kg</guid>
      <description>&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;API (Application Programming Interface)&lt;/strong&gt;: Là tập hợp các quy tắc và cơ chế cho phép các thành phần phần mềm giao tiếp với nhau. API thường trả về dữ liệu dưới dạng JSON hoặc XML.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;REST (REpresentational State Transfer)&lt;/strong&gt;: Là một kiểu kiến trúc để thiết kế API, sử dụng các phương thức HTTP như GET, POST, DELETE,... để giao tiếp giữa các máy tính. REST cho phép sử dụng URL để xử lý và chuyển đổi dữ liệu.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RESTful API&lt;/strong&gt;: Là tiêu chuẩn thiết kế API dựa trên kiến trúc REST. RESTful API được sử dụng rộng rãi cho các ứng dụng web, di động để quản lý và giao tiếp với các tài nguyên (resources).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Các phương thức HTTP phổ biến&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;GET&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Phương thức GET được sử dụng để yêu cầu dữ liệu từ một tài nguyên trên máy chủ. Phương thức này có tính bất biến nên có thể gọi nhiều lần mà vẫn ra cùng 1 kết quả cho đến khi một phương thức khác làm thay đổi tài nguyên. Không có body.&lt;/li&gt;
&lt;li&gt;Sử dụng khi muốn lấy dữ liệu mà không thay đổi trạng thái của tài nguyên. Ví dụ lấy dữ liệu để hiển thị ra màn hình.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;POST&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Phương thức POST được sử dụng để gửi dữ liệu đến máy chủ để tạo một tài nguyên mới. POST không có tính bất biến vì vậy khi gửi 2 yêu cầu giống hệt nhau sẽ tạo ra 2 tài nguyên khác nhau, cùng dữ liệu (trừ ID). Có body.&lt;/li&gt;
&lt;li&gt;Sử dụng khi muốn tạo mới một tài nguyên. Ví dụ dùng để tạo tài khoản cho người dùng, tạo sản phẩm mới,...&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;PUT&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Phương thức PUT được sử dụng để cập nhật toàn bộ thông tin của tài nguyên hiện có trên máy chủ. Có body.&lt;/li&gt;
&lt;li&gt;Sử dụng khi muốn cập nhật toàn bộ thông tin của một tài nguyên.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;PATCH&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Phương thức PATCH được sử dụng để cập nhật một phần thông tin của tài nguyên hiện có trên máy chủ. Có body.&lt;/li&gt;
&lt;li&gt;Sử dụng khi muốn cập nhật một phần cụ thể của tài nguyên.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;DELETE&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Phương thức DELETE được sử dụng để xóa một tài nguyên khỏi máy chủ.&lt;/li&gt;
&lt;li&gt;Sử dụng khi muốn xóa một tài nguyên. Không có body.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;OPTIONS&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Phương thức OPTIONS được sử dụng để mô tả các tùy chọn giao tiếp cho tài nguyên mục tiêu. Nó trả về các phương thức HTTP mà máy chủ hỗ trợ cho URL cụ thể đó. Không có body.&lt;/li&gt;
&lt;li&gt;Sử dụng khi muốn kiểm tra các phương thức HTTP được phép sử dụng cho một tài nguyên hoặc kiểm tra cấu hình của máy chủ mà không thực hiện bất kỳ hành động cụ thể nào.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Trong RESTful APIs, &lt;strong&gt;"body"&lt;/strong&gt; là phần dữ liệu được gửi kèm với yêu cầu hoặc phản hồi HTTP. Body có thể chứa bất kỳ dữ liệu nào mà máy chủ hoặc máy khách muốn truyền tải.&lt;br&gt;
Các phương thức GET và DELETE thường không có body, vì GET chỉ yêu cầu dữ liệu từ máy chủ và DELETE chỉ yêu cầu xóa một tài nguyên cụ thể. Phương thức POST, PUT và PATCH thường có body để truyền tải thông tin dữ liệu cần thiết cho máy chủ xử lý.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Status Codes</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 01 Mar 2025 21:04:35 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/status-codes-h5c</link>
      <guid>https://forem.com/dvphuc_175/status-codes-h5c</guid>
      <description>&lt;p&gt;Status codes trong HTTP phản ánh kết quả của một yêu cầu HTTP từ máy khách tới máy chủ. Các mã trạng thái này giúp máy khách biết kết quả của yêu cầu và hành động tiếp theo cần thực hiện. Dưới đây là một số nhóm mã trạng thái phổ biến và ý nghĩa của chúng:&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2xx: Success (Thành công)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;200 OK: Yêu cầu thành công.&lt;/li&gt;
&lt;li&gt;201 Created: Tài nguyên mới đã được tạo.&lt;/li&gt;
&lt;li&gt;204 No Content: Yêu cầu thành công nhưng không có nội dung trả về.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3xx: Redirection (Chuyển hướng)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;301 Moved Permanently: URL đã thay đổi vĩnh viễn.&lt;/li&gt;
&lt;li&gt;302 Found: URL tạm thời thay đổi.&lt;/li&gt;
&lt;li&gt;304 Not Modified: Không có thay đổi từ lần yêu cầu cuối.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4xx: Client Error (Lỗi từ phía khách hàng)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;400 Bad Request: Yêu cầu không hợp lệ.&lt;/li&gt;
&lt;li&gt;401 Unauthorized: Người dùng chưa được xác thực.&lt;/li&gt;
&lt;li&gt;403 Forbidden: Người dùng không có quyền truy cập.&lt;/li&gt;
&lt;li&gt;404 Not Found: Không tìm thấy tài nguyên.&lt;/li&gt;
&lt;li&gt;405 Method Not Allowed: Phương thức không được phép.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5xx: Server Error (Lỗi từ phía máy chủ)&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;500 Internal Server Error: Lỗi từ phía máy chủ.&lt;/li&gt;
&lt;li&gt;502 Bad Gateway: Máy chủ đóng vai trò là gateway hoặc proxy và nhận được phản hồi không hợp lệ từ máy chủ khác.&lt;/li&gt;
&lt;li&gt;503 Service Unavailable: Dịch vụ không khả dụng.&lt;/li&gt;
&lt;li&gt;504 Gateway Timeout: Máy chủ đóng vai trò là gateway hoặc proxy và không nhận được phản hồi kịp thời từ máy chủ khác.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Quy chuẩn đặt tên trong thiết kế RESTful API</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 01 Mar 2025 20:57:04 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/quy-chuan-dat-ten-trong-thiet-ke-restful-api-52h</link>
      <guid>https://forem.com/dvphuc_175/quy-chuan-dat-ten-trong-thiet-ke-restful-api-52h</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Khái quát về các loại Resource&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Singleton and Collection Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ví dụ, "Customers" là Collection Resources, "Customer" là Singleton Resources.&lt;br&gt;
Đối với collection resource trên, chúng ta có thể xác định nó bằng URI " &lt;code&gt;/customers&lt;/code&gt;". Còn đối với singleton resource, chúng ta sử dụng &lt;code&gt;/customers/{customerId}&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Collection and Sub-collection Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Một Resource cũng có thể chứa nhiều các tập hợp khác (sub-collection). Ví dụ một chủ thể &lt;strong&gt;customer&lt;/strong&gt; nắm giữ thông tin của các tài khoản &lt;strong&gt;accounts&lt;/strong&gt; khác nhau. Chúng ta có thể định danh API này bằng URN: &lt;code&gt;/customers/{customerId}/accounts&lt;/code&gt; để lấy toàn bộ thông tin sub-collection tài khoản của 1 user bất kì. Tương tự nếu muốn lấy 1 &lt;strong&gt;singleton resource account&lt;/strong&gt; của &lt;strong&gt;accounts&lt;/strong&gt; : &lt;code&gt;/customers/{customerId}/accounts/{accountId}&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Một vài lời khuyên đặt tên cho URI&lt;/strong&gt;
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Sử dụng danh từ để đại diện cho Resource.&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;RESTful API nên liên quan tới resource là một danh từ chỉ đối tượng thay vì một động từ chỉ hành động vì danh từ thường có các thuộc tính (properties) mà đông từ không có, cũng giống như resource thì thường có các attributes đi kèm.&lt;br&gt;
Đi sâu hơn về phần này, chúng ta sẽ chia các API ra thành 4 nhóm: document, collection, store và controller. Tuỳ vào mục đích sử dụng, chúng ta chia các api ra các nhóm để sử dụng convension sao cho phù hợp nhất.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a. Document&lt;/strong&gt;&lt;br&gt;
Là resource chỉ các đối tượng độc lập, hay 1 bản ghi trong database. Nó là 1 singleton resource bên trong collection resource. Sử dụng danh từ số ít hoặc định danh của resource cho loại này.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/{id}
http://api.example.com/user-management/users/admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;b. Collection&lt;/strong&gt;&lt;br&gt;
Là các resource được quản lý bởi server. Client có thể yêu cầu thêm các resource mới vào collection. Tuy nhiên, việc có được thêm hay không lại phụ thuộc vào bên thứ 3 (admin hoặc chính collection đó quy định).&lt;/p&gt;

&lt;p&gt;Sử dụng các tên số nhiều với type này.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/device-management/managed-devices
http://api.example.com/api/user-management/users
http://api.example.com/api/user-management/users/{id}/accounts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;c. Store&lt;/strong&gt;&lt;br&gt;
Là các resource được quản lý bởi client - tức là người sử dụng API đó. Client có toàn quyền CRUD với resource này. Loại resource này chỉ nên có 1 URI, và không nên tạo ra các URI khác.&lt;/p&gt;

&lt;p&gt;Với các type này, chúng ta sử dụng các tên số nhiều.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/song-management/users/{id}/playlists
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;d. Controller&lt;/strong&gt;&lt;br&gt;
Loại resoure này như đại diện cho 1 hành động, 1 quá trình và có input-output, hoặc 1 giá trị.&lt;/p&gt;

&lt;p&gt;Với các type này, hơi đặc biệt 1 chút. chúng ta nên sử dụng động từ để dễ hình dung.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/auth/login
http://api.example.com/api/send-mail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nhất quán URI theo một chuẩn chung
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Dưới đây là một số quy tắc chung được cộng đồng khuyên dùng:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;a. Sử dụng "/" để ngăn cách quan hệ trong resource&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/song-management/users/{id}/playlists
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;b. Không sử dụng "/" cuối API&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/auth/login/ -&amp;gt;không nên
http://api.example.com/api/auth/login -&amp;gt; nên
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;c.  Sử dụng "-"&lt;/strong&gt;&lt;br&gt;
Để tăng khả năng đọc liền mạch đối với các path dài. Ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/messenger-management/group-chat/{id}/download-archived-conversation -&amp;gt; nên
http://api.example.com/api/messengerManagement/groupChat/{id}/downloadArchivedConversation -&amp;gt; không nên
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;d. Không sử dụng "_"&lt;/strong&gt;&lt;br&gt;
Bạn cũng có thể sử dụng "_" thay cho "-" để ngăn cách các segment. Tuy nhiên với 1 số các ứng dụng sử dụng các custom font, dấu gạch dưới sẽ rất khó hoặc hoàn toàn không nhìn thấy. Để tăng khả năng đọc, chúng ta hãy thống nhất dùng "-" nhé.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/messenger-management/group-chat/{id}/download-archived-conversation -&amp;gt; nên
http://api.example.com/api/messenger_management/group_chat/{id}/download_archived_conversation -&amp;gt; không nên
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;e. Sử dụng chữ cái thường&lt;/strong&gt;&lt;br&gt;
Do RFC 3986 quy định, trừ scheme và host, path của URI sẽ phải check các case liên quan đến chữ viết hoa và viết thường.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.org/my-folder/my-doc  //1 -&amp;gt; giống với 2
HTTP://API.EXAMPLE.ORG/my-folder/my-doc  //2 -&amp;gt; giống với 1
http://api.example.org/My-Folder/my-doc  //3 -&amp;gt; khác 1 và 2 do path có chữ viết hoa
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vì vậy để thuận tiện, chúng ta nên sử dụng hoàn toàn chữ cái thường.&lt;/p&gt;

&lt;h2&gt;
  
  
  f. Không sử dụng định dạng file
&lt;/h2&gt;

&lt;p&gt;Việc sử dụng định dạng file trên URI không có tác dụng gì và trông rất tệ. Nếu muốn truyền file, bạn nên giao tiếp qua API thông qua body của request với Content-Type header.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://api.example.com/api/messenger-management/group-chat/{id}/download-archived-conversation -&amp;gt; nên
http://api.example.com/api/messenger-management/group-chat/{id}/download-archived-conversation.json -&amp;gt; không nên

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Tham khảo thêm:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://blog.vietnamlab.vn/restful-api-convention/" rel="noopener noreferrer"&gt;https://blog.vietnamlab.vn/restful-api-convention/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://restfulapi.net/resource-naming/" rel="noopener noreferrer"&gt;https://restfulapi.net/resource-naming/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Cấu trúc URL</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 01 Mar 2025 18:55:20 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/cau-truc-url-327o</link>
      <guid>https://forem.com/dvphuc_175/cau-truc-url-327o</guid>
      <description>&lt;p&gt;Một trang web thông thường có ít nhất 3 phần trong URL như &lt;a href="http://www.google.com" rel="noopener noreferrer"&gt;www.google.com&lt;/a&gt; nhưng một số URL phức tạp cũng có thể có 8 đến 9 phần như dưới đây:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29xg4xzh2pk7snbm1jd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F29xg4xzh2pk7snbm1jd5.png" alt="Image description" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Scheme&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Scheme là thành phần đầu tiên của URL và nó có nhiệm vụ xác định giao thức truyền tải được sử dụng để truy cập vào tài nguyên. Các giao thức phổ biến như: http, https, ftp, file,...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Subdomain (Tên miền phụ)&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;https://&lt;strong&gt;www.&lt;/strong&gt;  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Đây thường được gọi là tên miền con của tên miền chính. Chính vì là miền con của miền chính nên tên miền con này mang đầy đủ những tính chất như một miền chính và chúng ta có thể sử dụng nó giống như miền chính. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Domain Name (Tên miền)&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;https://www.**example.**&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Tên miền thể hiện tổ chức hoặc cá nhân sở hữu trang web đó.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Top-level Domain&lt;/strong&gt;
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;https://www.example.**com**&lt;/code&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Thể hiện loại tổ chức mà trang web được đăng kí, .com (thương mại), .edu(giáo dục), .gov(chính phủ), .vn (Việt Nam)...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Port number&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Port number (số cổng) trong URL là một giá trị số giúp xác định dịch vụ nào trên máy chủ sẽ xử lý yêu cầu. Nó thường xuất hiện sau dấu : ngay sau tên miền hoặc địa chỉ IP.&lt;br&gt;
Thông thường các trang web sử dụng http, https sẽ dùng cổng mặc định là 80, 443 nên không hiển thị cổng.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Path Parameter&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Path Parameter (tham số đường dẫn) là một phần của URL được sử dụng để xác định một tài nguyên cụ thể trên server. Path Parameter là một phần cố định trong URL và không thể bỏ qua.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;https://api.com/users/{userId}&lt;/code&gt; &lt;br&gt;
&lt;strong&gt;userId&lt;/strong&gt; là tham số đường dẫn xác định ID của một người dùng cụ thể.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Query Parameters&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Query Parameters (tham số truy vấn) là phần trong URL dùng để truyền dữ liệu đến server. Nó bắt đầu bằng dấu "?" và bao gồm các cặp key=value, các cặp này được ngăn cách bằng dấu "&amp;amp;". &lt;/li&gt;
&lt;li&gt;Thường được sử dụng để lọc, sắp xếp, phân trang vì nó có thể truy vấn đến nhiều dữ liệu.&lt;/li&gt;
&lt;li&gt;Dấu ? được sử dụng để bắt đầu phần query parameters trong URL.&lt;/li&gt;
&lt;li&gt;Dấu &amp;amp; được sử dụng để ngăn cách nhiều query parameters trong URL. Sử dụng khi có nhiều tham số truy vấn và ngăn cách các tham số đó.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;https://api.com/search?query=books&amp;amp;sort=asc&amp;amp;page=2&lt;/code&gt; &lt;br&gt;
Ví dụ truy vấn đến mục sách, sắp xếp tăng dần, trang số 2&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>JSON</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sun, 23 Feb 2025 03:29:09 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/json-57ba</link>
      <guid>https://forem.com/dvphuc_175/json-57ba</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;JSON viết tắt của JavaScript Object Notation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Là một định dạng dữ liệu được lưu dưới dạng chuỗi.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Chỉ cho phép các kiểu dữ liệu cơ bản: number, string, boolean, array, object, null.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Không cho phép: function, date, undefined.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trường hợp giá trị của JSON là dạng Object thì:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Có các cặp key/value.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Key: đặt trong dấu nháy kép.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Không có dấu phẩy ở cặp key/value cuối cùng.&lt;br&gt;
Chuyển đổi JSON trong JavaScript&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JavaScript cung cấp hai phương thức chính để làm việc với JSON:&lt;/p&gt;

&lt;p&gt;Chuyển từ JSON sang JavaScript object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsonData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chuyển từ JavaScript object sang JSON:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;jsonString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Ứng dụng của JSON&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trao đổi dữ liệu giữa client và server.&lt;/li&gt;
&lt;li&gt;Lưu trữ cấu hình ứng dụng.&lt;/li&gt;
&lt;li&gt;Dùng trong NoSQL daâtbases.&lt;/li&gt;
&lt;li&gt;Truyền dữ liệu trong các ứng dụng.
…&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Node.JS, NPM</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 22 Feb 2025 19:53:49 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/nodejs-npm-1na4</link>
      <guid>https://forem.com/dvphuc_175/nodejs-npm-1na4</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Node.JS&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Node.JS là mã nguồn mở dùng để chạy Javascript đa nền tảng.&lt;/li&gt;
&lt;li&gt;Trước đây, Javascript chỉ chạy ở môi trường trình duyệt bên phía front-end.&lt;/li&gt;
&lt;li&gt;Hiện nay, Node.JS sinh ra đóng vai trò làm môi trường để Javascript có thể chạy trên môi trường khác.&lt;/li&gt;
&lt;li&gt;Download và cài đặt: &lt;a href="//https://%0Anodejs.org/en"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Kiểm tra version: &lt;strong&gt;node -v&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;So sánh Node.JS và Javascript:&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Javascript:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Là ngôn ngữ lập trình.&lt;/li&gt;
&lt;li&gt;Chủ yếu dùng để phát triển các ứng dụng web phía client (trình duyệt).&lt;/li&gt;
&lt;li&gt;Chạy trên trình duyệt web.&lt;/li&gt;
&lt;li&gt;Chạy mã đồng bộ bà bất đồng bộ&lt;/li&gt;
&lt;li&gt;Các thư viện và framework phổ biến: React.js, Angular, Vue.js.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Node.js:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Là môi trường chạy Javascript phía server.&lt;/li&gt;
&lt;li&gt;Cho phép chạy mã Javascript ngoài trình duyệt.&lt;/li&gt;
&lt;li&gt;Được tối ưu hoá cho các hoạt động bất đồng bộ và I/O.&lt;/li&gt;
&lt;li&gt;Các thư viện và framework phổ biến: Express.js, Nest.js,...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;NPM&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;NPM (Node Package Manager) là một công cụ tạo và quản lý các thư viện lập trình Javascript cho Node.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Không sử dụng NPM, bạn sẽ cần tải toàn bộ các thư viện một cách thủ công. Sau đó, bạn cần thực hiện nhúng thư viện vào dự án của mình. Điều này sẽ làm mất nhiều thời gian hơn để hoàn thành.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Khi sử dụng NPM, chỉ cần 1 dòng lệnh hoàn tất công việc lưu thư viện.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Link website: &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Cài đặt và sử dụng NPM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;NPM được tích hợp sẵn trong Node.js, nên chỉ cần cài Node.js là được.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gõ lệnh &lt;strong&gt;npm -v&lt;/strong&gt; trên &lt;strong&gt;cmd&lt;/strong&gt; để kiểm tra phiên bản.&lt;/li&gt;
&lt;li&gt;Để thêm NPM vào project, gõ lệnh &lt;strong&gt;npm init&lt;/strong&gt;, sau đó enter đến hết. Câu lệnh này sẽ tạo ra 1 file có tên là &lt;strong&gt;package.json&lt;/strong&gt; - lưu trữ thông tin (tên package, phiên bản, các dependencies) mà project sử dụng.&lt;/li&gt;
&lt;li&gt;Gõ lệnh &lt;strong&gt;npm install [tên package]&lt;/strong&gt; hoặc &lt;strong&gt;npm i [tên package]&lt;/strong&gt; để cài đặt package vào project.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Một số thuộc tính trong package.json&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: tên gói thư viện.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;version&lt;/strong&gt;: phiên bản gói.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;description&lt;/strong&gt;: phần mô tả về gói thư viện.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;homepage&lt;/strong&gt;: trang chủ của gói.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;author&lt;/strong&gt;: tác giả.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;contributors&lt;/strong&gt;: tên người đóng góp cho package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;dependencies&lt;/strong&gt;: danh sách các gói phụ thuộc, tự động được cài theo.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;repository&lt;/strong&gt;: loại repository và url của package, thông thường là link git.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;main&lt;/strong&gt;: index.js (file chính của dự án).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;keywords&lt;/strong&gt;: các từ khóa.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Một số câu lệnh npm khác&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;npm update [tên_package]&lt;/strong&gt;: Để update một package. Hạn chế dùng, chỉ dùng khi thực sự hiểu về package bạn đang muốn update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm uninstall [tên_package]&lt;/strong&gt;: Gỡ cài đặt package.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>node</category>
    </item>
    <item>
      <title>Fetch API</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 22 Feb 2025 19:52:27 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/fetch-api-310h</link>
      <guid>https://forem.com/dvphuc_175/fetch-api-310h</guid>
      <description>&lt;ul&gt;
&lt;li&gt;Phương thức Fetch dùng để gọi lên trên server thông qua một API để lấy dữ liệu từ trên server trả về. Nó là một phương thức bất đồng bộ (asynchronous) và trả về một Promise.&lt;/li&gt;
&lt;li&gt;Api là một url để cho phép bên Front-end có thể giao tiếp được với bên Back-end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cú pháp:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://example.com/movies.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trong đó:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetch(): Dùng để gửi yêu cầu lên server thông qua api.&lt;/li&gt;
&lt;li&gt;response.json(): Chuyển đổi phản hồi thành JSON.&lt;/li&gt;
&lt;li&gt;then(): Được thực thi khi có phản hồi từ server trả về.&lt;/li&gt;
&lt;li&gt;catch(): Bắt lỗi nếu request thất bại.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>api</category>
      <category>frontend</category>
      <category>typescript</category>
    </item>
    <item>
      <title>ExpressJS</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Sat, 22 Feb 2025 19:51:50 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/expressjs-5d4b</link>
      <guid>https://forem.com/dvphuc_175/expressjs-5d4b</guid>
      <description>&lt;p&gt;Express.js là một framework web cho Node.js giúp xây dựng ứng dụng backend một cách nhanh chóng và linh hoạt. Đây là một trong những framework phổ biến nhất khi phát triển REST API hoặc ứng dụng web.&lt;/p&gt;

&lt;p&gt;Cài đặt: &lt;a href="https://www.npmjs.com/package/express" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/express&lt;/a&gt;&lt;br&gt;
Docs &amp;amp; community: &lt;a href="https://expressjs.com/" rel="noopener noreferrer"&gt;https://expressjs.com/&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Đặc điểm nổi bật của Express.js&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Nhẹ &amp;amp; tối giản: Chỉ cung cấp những tính năng cần thiết cho ứng dụng web.&lt;/li&gt;
&lt;li&gt;Dễ dàng mở rộng: Hỗ trợ middleware để xử lý yêu cầu và phản hồi.&lt;/li&gt;
&lt;li&gt;Hỗ trợ routing mạnh mẽ: Dễ dàng định nghĩa các tuyến đường (routes) cho API.&lt;/li&gt;
&lt;li&gt;Tích hợp với nhiều template engine: Như Pug, EJS, Handlebars.&lt;/li&gt;
&lt;li&gt;Tương thích với nhiều database.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Cách hoạt động của Express.js&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Express giúp xử lý các yêu cầu HTTP bằng cách sử dụng middleware và routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nhận yêu cầu từ client.&lt;/li&gt;
&lt;li&gt;Xử lý yêu cầu thông qua middleware&lt;/li&gt;
&lt;li&gt;Trả về phản hồi cho client.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  &lt;strong&gt;Cấu trúc cơ bản của một project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Khi tạo một project, thường có cấu trúc thư mục như sau:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/my-project
│── /node_modules        # Thư viện npm
│── /routes              # Các route của API
│── /controllers         # Xử lý logic
│── /middlewares         # Middleware (xác thực, log,...)
│── /public              # Chứa file tĩnh (CSS, JS, images)
│── /views               # Template engine (nếu có)
│── app.js               # File chính
│── package.json         # Danh sách dependencies

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Một số khái niệm&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Khởi tạo express&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Example app listening on port &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;port&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Middleware&lt;/strong&gt;&lt;br&gt;
Middleware là các hàm trung gian giúp xử lý request trước khi gửi phản hồi.&lt;br&gt;
Ví dụ về middleware:&lt;br&gt;
&lt;strong&gt;Routing&lt;/strong&gt;&lt;br&gt;
Định nghĩa các tuyến đường (routes) để xử lý các yêu cầu cụ thể.&lt;br&gt;
...&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Cài Nodemon&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Nodemon là một công cụ phục vụ cho NodeJS.&lt;br&gt;
Giúp tự động khởi động lại ứng dụng khi phát hiện các thay đổi của tệp.&lt;br&gt;
Link NPM: &lt;a href="https://www.npmjs.com/package/nodemon" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/nodemon&lt;/a&gt;&lt;br&gt;
Hướng dẫn cài đặt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bước 1: Chạy câu lệnh &lt;strong&gt;npm i --save-dev nodemon&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Bước 2: Thêm dòng &lt;strong&gt;"start": "nodemon --inspect index.js"&lt;/strong&gt; vào mục &lt;strong&gt;script&lt;/strong&gt; trong file &lt;strong&gt;package.json&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Bước 3: Chạy &lt;strong&gt;npm start&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>express</category>
    </item>
    <item>
      <title>Đồng bộ (synchronous) và Bất đồng bộ (asynchronous)</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Tue, 18 Feb 2025 14:41:24 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/dong-bo-synchronous-va-bat-dong-bo-asynchronous-4g1h</link>
      <guid>https://forem.com/dvphuc_175/dong-bo-synchronous-va-bat-dong-bo-asynchronous-4g1h</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Đồng bộ (synchronous)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Đồng bộ trong lập trình là các tác vụ trong chương trình được thực thi một cách tuần tự, nghĩa là mỗi tác vụ phải hoàn thành trước khi tác vụ tiếp theo có thể bắt đầu. Khi một tác vụ đồng bộ đang được thực hiện, toàn bộ chương trình sẽ phải chờ cho đến khi tác vụ đó hoàn thành mới tiếp tục thực thi các tác vụ khác. Điều này có thể dẫn đến việc chương trình bị "đóng băng" hoặc không phản hồi khi thực hiện các tác vụ nặng hoặc mất thời gian.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;program1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;program2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;program1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;program2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//Output:&lt;/span&gt;
&lt;span class="c1"&gt;//Program 1&lt;/span&gt;
&lt;span class="c1"&gt;//Program 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Bất đồng bộ (asynchronous)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Bất đồng bộ trong lập trình là khi một tác vụ có thể xảy ra mà không làm ngừng hoặc chặn luồng thực thi chính của chương trình. Điều này có nghĩa là các tác vụ nặng nề hoặc mất nhiều thời gian (như truy vấn dữ liệu từ server, đọc/ghi tệp lớn) có thể được thực hiện "ngầm" trong khi chương trình tiếp tục xử lý các tác vụ khác.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;program1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="p"&gt;},);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;program2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;program1&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;program2&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//Output:&lt;/span&gt;
&lt;span class="c1"&gt;//Program 2&lt;/span&gt;
&lt;span class="c1"&gt;//Program 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Xử lí bất đồng bộ&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;JavaScript thực chất là ngôn ngữ đơn luồng và chạy đồng bộ. &lt;br&gt;
Tuy nhiên, để tránh việc bị chặn khi thực hiện các tác vụ nặng (như đọc/ghi tệp lớn, truy vấn dữ liệu từ server,...) mà vẫn tiếp tục xử lý các đoạn code khác, JavaScript sử dụng cơ chế bất đồng bộ thông qua môi trường thực thi (browser hoặc Node.js) để xử lý các tác vụ như I/O, timers và events. Tuy nhiên, để lập trình viên có thể tương tác và làm việc với các tác vụ bất đồng bộ này, họ cần sử dụng các công cụ như callback, promise, hoặc async/await. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Callback, Promise, Async/Await</title>
      <dc:creator>Do Van Phuc</dc:creator>
      <pubDate>Tue, 11 Feb 2025 14:56:26 +0000</pubDate>
      <link>https://forem.com/dvphuc_175/callback-313b</link>
      <guid>https://forem.com/dvphuc_175/callback-313b</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Callback&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Callback là một hàm được truyền qua đối số trong 1 hàm khác (tạm gọi là hàm cha). Khi hàm cha được gọi, hàm callback sẽ được thực thi sau khi một số hành động cụ thể trong hàm cha hoàn thành.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Callback giúp JavaScript mạnh mẽ hơn trong xử lý bất đồng bộ, tùy chỉnh cách xử lý mà không cần sửa đổi code gốc, tái sử dụng code, xử lý sự kiện,...&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ví dụ về callback&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hàm truyền vào cho setTimeout ở tham số thứ nhất là hàm callback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Ví dụ 1:&lt;/span&gt;
    &lt;span class="c1"&gt;// Hàm này sẽ chạy sau 1 giây do setTimeout là bất đồng bộ&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Hàm program2 nhận một callback và thực thi nó ngay sau khi log "Program 2"&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;program2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Gọi hàm callback được truyền vào&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Gọi program2 và truyền vào một callback (hàm program3)&lt;/span&gt;
    &lt;span class="nf"&gt;program2&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Program 3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="c1"&gt;// Output: &lt;/span&gt;
    &lt;span class="c1"&gt;// Program 2&lt;/span&gt;
    &lt;span class="c1"&gt;// Program 3&lt;/span&gt;
    &lt;span class="c1"&gt;// Program 1 &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Hàm setTimeout được gọi nhưng chưa thực thi ngay.&lt;/li&gt;
&lt;li&gt;Hàm setTimeout sẽ đưa callback (hàm Program 1) vào hàng đợi và chờ 1 giây và thực hiện dòng mã tiếp theo in ra hàm &lt;strong&gt;"Program 2"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Hàm program3 (callback) được truyền vào program2 và thực thi in ra &lt;strong&gt;"Program 3"&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Sau 1 giây, callback trong setTimeout mới thực thi in ra &lt;strong&gt;"Program 1"&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Ví dụ 2&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;kiemTraSoDuong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Đây là số dương&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Đây là số âm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tinhTong&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ketQua&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;
        &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ketQua&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;tinhTong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kiemTraSoDuong&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//Ví dụ 3:&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loginSucces&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Đăng nhập thành công&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkLogin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tendangnhap@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;password&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Đăng nhập thất bại&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;user1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tendangnhap@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;password&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1234&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nf"&gt;checkLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;loginSucces&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Callback Hell&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Callback Hell là một tình huống trong JavaScript khi nhiều hàm callback lồng nhau khiến mã khó đọc và khó bảo trì.&lt;br&gt;
Điều này thường xảy ra khi xử lý các hoạt động bất đồng bộ, như tạo yêu cầu API hoặc xử lý tệp I/O, trong đó một hoạt động phụ thuộc vào kết quả của hoạt động khác hoặc hoạt động trước đó.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjwxw18txa5m1fzshgks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqjwxw18txa5m1fzshgks.png" alt="Image description" width="800" height="420"&gt;&lt;/a&gt;&lt;br&gt;
Giải pháp là có thể sử dụng Promise hoặc Async/Await để code trở lên dễ đọc hơn.&lt;/p&gt;
&lt;h1&gt;
  
  
  &lt;strong&gt;Promise&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Promise có 3 trạng thái:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pending:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Khi promise đang chạy thì sẽ ở trạng thái này.&lt;/li&gt;
&lt;li&gt;Kết quả là undefined.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fulfilled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Khi promise đã chạy xong thì sẽ ở trạng thái này.&lt;/li&gt;
&lt;li&gt;Kết quả là một giá trị.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rejected:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Khi promise bị lỗi thì sẽ ở trạng thái này.&lt;/li&gt;
&lt;li&gt;Kết quả là một object lỗi.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cú pháp:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//resolve() : Nếu thành công chyạ vào hàm này&lt;/span&gt;
    &lt;span class="c1"&gt;//reject() : Nếu thất bại chạy vào hàm này&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="nx"&gt;promise&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;success&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Nếu thành công chạy vào đây&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Nếu thành công chạy vào đây&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//Luôn luôn chạy vào đây&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ví dụ:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;promise&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resultA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;resultA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resultA&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resultA&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;resultB&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resultB&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resultB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;catch&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thất bại!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;finally&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Luôn chạy vào đây!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Trong ví dụ này, a = 10 nên hàm resolve được gọi, truyền giá trị 10 vào phương thức then() đầu tiên.&lt;/li&gt;
&lt;li&gt;Phương thức then() đầu tiên nhận được giá trị 10 và ghi ra console, sau đó trả lại giá trị 10.&lt;/li&gt;
&lt;li&gt;Phương thức then() thứ hai nhận được giá trị 10 từ then() trước, cộng thêm 10 để thành 20 và ghi ra console, sau đó trả lại giá trị 20.&lt;/li&gt;
&lt;li&gt;Phương thức then() thứ ba nhận được giá trị 20 từ then() trước, nhân với 20 để thành 400 và ghi ra console.&lt;/li&gt;
&lt;li&gt;Cuối cùng, finally() luôn được thực thi bất kể Promise hoàn thành hay bị từ chối, và console "Luôn chạy vào đây!".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Promise khiến code trở nên dễ hiểu hơn, xử lí được callback hell.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Async/Await&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Async/Await là một tính năng của JavaScript giúp chúng ta làm việc với các hàm bất đồng bộ theo cách dễ hiểu hơn.&lt;br&gt;
Nó được xây dựng trên Promise.&lt;br&gt;
&lt;strong&gt;Async:&lt;/strong&gt; Khai báo một hàm bất đồng bộ.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tự động biến đổi một hàm thông thường thành một Promise.&lt;/li&gt;
&lt;li&gt;Từ khóa Async được đặt trước 1 hàm.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Await:&lt;/strong&gt; Tạm dừng việc thực hiện các hàm async.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Khi được đặt trước một Promise, nó sẽ đợi cho đến khi Promise kết thúc và trả về kết quả.&lt;/li&gt;
&lt;li&gt;Await chỉ có thể được sử dụng bên trong các hàm async.
Ví dụ:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getResult&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Thất bại!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultA&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultB&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resultA&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resultC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;resultB&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;resultC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nf"&gt;getResult&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
