aboutsummaryrefslogtreecommitdiff
path: root/files/vi/learn/server-side/express_nodejs/displaying_data
diff options
context:
space:
mode:
Diffstat (limited to 'files/vi/learn/server-side/express_nodejs/displaying_data')
-rw-r--r--files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html135
-rw-r--r--files/vi/learn/server-side/express_nodejs/displaying_data/index.html98
2 files changed, 233 insertions, 0 deletions
diff --git a/files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html b/files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html
new file mode 100644
index 0000000000..6d5192d404
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/displaying_data/flow_control_using_async/index.html
@@ -0,0 +1,135 @@
+---
+title: Kiểm soát luồng không đồng bộ bằng cách sử dụng async
+slug: Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async
+translation_of: Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async
+---
+<p>Mã điều khiển cho một số trang <em>LocalLibrary</em> của chúng tôi sẽ phụ thuộc vào kết quả của nhiều yêu cầu bất đồng bộ, có thể được yêu cầu chạy theo một số thứ tự cụ thể hoặc song song. Để quản lý kiểm soát dòng chảy, và đưa ra trang khi chúng tôi có tất cả các thông tin cần thiết có sẵn, chúng tôi sẽ sử dụng các nút phổ biến <a class="external external-icon" href="https://www.npmjs.com/package/async" rel="noopener">async</a> module.</p>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Có một số cách khác để quản lý hành vi bất đồng bộ và kiểm soát luồng trong JavaScript, bao gồm các tính năng ngôn ngữ JavaScript tương đối gần đây như <a href="https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/Techniques/Promises">Promises</a>.</p>
+</div>
+
+<p>Async có rất nhiều phương pháp hữu ích (xem <a class="external external-icon" href="http://caolan.github.io/async/docs.html" rel="noopener">tài liệu</a> ). Một số chức năng quan trọng hơn là:</p>
+
+<ul>
+ <li><code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#parallel" rel="noopener">async.parallel()</a></code> để thực hiện bất kỳ thao tác nào phải được thực hiện song song.</li>
+ <li><code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#series" rel="noopener">async.series()</a></code> khi chúng ta cần đảm bảo rằng các hoạt động bất đồng bộ được thực hiện theo chuỗi.</li>
+ <li><code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#waterfall" rel="noopener">async.waterfall()</a></code> cho các hoạt động phải được chạy theo chuỗi, với mỗi thao tác tùy thuộc vào kết quả của các phép toán trước đó.</li>
+</ul>
+
+<h2 id="Tại_sao_nó_cần_thiết">Tại sao nó cần thiết?</h2>
+
+<p>Hầu hết các phương thức chúng tôi sử dụng trong <em>Express</em> đều bất đồng bộ — bạn chỉ định một thao tác để thực hiện, chuyển một cuộc gọi lại. Phương thức trả về ngay lập tức và gọi lại được gọi khi hoạt động được yêu cầu hoàn tất. Theo quy ước trong <em>Express</em> , hàm gọi lại truyền giá trị <em>lỗi</em> làm tham số đầu tiên (hoặc <code>null</code>thành công) và kết quả từ hàm (nếu có) làm tham số thứ hai.</p>
+
+<p>Nếu một bộ điều khiển chỉ cần <em>thực hiện <strong>một</strong> thao tác bất đồng bộ</em> để có được thông tin cần thiết để hiển thị một trang thì việc triển khai thực hiện rất dễ dàng — chúng tôi chỉ cần hiển thị mẫu trong cuộc gọi lại. Đoạn mã dưới đây cho thấy điều này cho một hàm làm cho số đếm của một mô hình <code>SomeModel</code>(sử dụng <code><a class="external external-icon" href="http://mongoosejs.com/docs/api.html#model_Model.count" rel="noopener">count()</a></code>phương thức Mongoose ):</p>
+
+<pre class="brush: js"><code>exports.some_model_count = function(req, res, next) {
+
+</code> SomeModel.count ({a_model_field: 'match_value'}, hàm (err, count) {
+ // ... làm gì đó nếu có lỗi
+
+  // Khi thành công, trả kết quả bằng cách chuyển số đếm vào hàm render (ở đây, dưới dạng biến 'data').
+  res.render ('the_template', {data: count});
+  });
+<code>}</code>
+</pre>
+
+<p>Tuy nhiên, nếu bạn cần thực hiện <strong>nhiều</strong> truy vấn bất đồng bộ và bạn không thể hiển thị trang cho đến khi tất cả các thao tác đã hoàn tất? Việc triển khai ngây thơ có thể "chuỗi daisy" các yêu cầu, khởi động các yêu cầu tiếp theo trong cuộc gọi lại của yêu cầu trước đó và hiển thị phản hồi trong cuộc gọi lại cuối cùng. Vấn đề với cách tiếp cận này là các yêu cầu của chúng tôi sẽ phải được chạy theo chuỗi, mặc dù nó có thể hiệu quả hơn để chạy chúng song song. Điều này cũng có thể dẫn đến mã lồng nhau phức tạp, thường được gọi là <a class="external external-icon" href="http://callbackhell.com/" rel="noopener">địa chỉ gọi lại</a> (<strong>callback hell</strong>) .</p>
+
+<p>Một giải pháp tốt hơn sẽ là thực hiện tất cả các yêu cầu song song và sau đó có một cuộc gọi lại duy nhất thực hiện khi tất cả các truy vấn đã hoàn thành. Đây là loại hoạt động lưu lượng mà mô-đun <em>Async</em> làm cho dễ dàng!</p>
+
+<h2 id="Hoạt_động_bất_đồng_bộ_song_song">Hoạt động bất đồng bộ song song</h2>
+
+<p>Phương pháp <code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#parallel" rel="noopener">async.parallel()</a></code>này được sử dụng để chạy nhiều hoạt động bất đồng bộ song song.</p>
+
+<p>Đối số đầu tiên <code>async.parallel()</code>là một tập hợp các hàm bất đồng bộ để chạy (một mảng, đối tượng hoặc có thể lặp lại khác). Mỗi chức năng được truyền <code>callback(err, result)</code>mà nó phải gọi khi hoàn thành với một lỗi <code>err</code>(có thể là <code>null</code>) và một <code>results</code>giá trị tùy chọn .</p>
+
+<p>Đối số thứ hai tùy chọn  <code>async.parallel()</code>là một cuộc gọi lại sẽ được chạy khi tất cả các hàm trong đối số đầu tiên đã hoàn thành. Gọi lại được gọi với một đối số lỗi và một bộ sưu tập kết quả có chứa các kết quả của các hoạt động bất đồng bộ riêng lẻ. Bộ sưu tập kết quả có cùng kiểu với đối số đầu tiên (tức là nếu bạn truyền một mảng các hàm bất đồng bộ, thì hàm gọi lại cuối cùng sẽ được gọi với một mảng các kết quả). Nếu bất kỳ hàm song song nào báo cáo lỗi thì gọi lại được gọi sớm (với giá trị lỗi).</p>
+
+<p>Ví dụ dưới đây cho thấy cách thức này hoạt động khi chúng ta truyền một đối tượng làm đối số đầu tiên. Như bạn có thể thấy, các kết quả được <em>trả về</em> trong một đối tượng có cùng tên thuộc tính như các hàm ban đầu được truyền vào.</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.parallel({
+ one: function(callback) { ... },
+ two: function(callback) { ... },
+ ...
+ something_else: function(callback) { ... }
+ },
+ // optional callback
+ function(err, results) {
+ // 'results' is now equal to: {one: 1, two: 2, ..., something_else: some_value}
+ }
+);</code></pre>
+
+<p>Nếu bạn thay vì truyền một mảng các hàm như đối số đầu tiên, kết quả sẽ là một mảng (kết quả thứ tự mảng sẽ khớp với thứ tự ban đầu mà các hàm được khai báo — không phải thứ tự mà chúng đã hoàn thành).</p>
+
+<h2 id="Các_hoạt_động_bất_đồng_bộ_trong_chuỗi">Các hoạt động bất đồng bộ trong chuỗi</h2>
+
+<p>Phương thức <code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#series" rel="noopener">async.series()</a></code>này được sử dụng để chạy nhiều hoạt động bất đồng bộ theo thứ tự, khi các hàm tiếp theo không phụ thuộc vào đầu ra của các hàm trước đó. Nó cơ bản được khai báo và cư xử theo cùng một cách như <code>async.parallel()</code>.</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.series({
+ one: function(callback) { ... },
+ two: function(callback) { ... },
+ ...
+ something_else: function(callback) { ... }
+ },
+ // optional callback after the last asynchronous function completes.
+ function(err, results) {
+ // 'results' is now equals to: {one: 1, two: 2, ..., something_else: some_value}
+ }
+);</code></pre>
+
+<div class="note">
+<p><strong>Lưu ý:</strong> Đặc tả ngôn ngữ ECMAScript (JavaScript) nói rằng thứ tự liệt kê một đối tượng là không xác định, vì vậy có thể các hàm sẽ không được gọi theo cùng thứ tự như bạn chỉ định chúng trên tất cả các nền tảng. Nếu thứ tự thực sự quan trọng, thì bạn nên chuyển một mảng thay vì một đối tượng, như hình dưới đây.</p>
+</div>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.series([
+ function(callback) {
+ // do some stuff ...
+ callback(null, 'one');
+ },
+ function(callback) {
+ // do some more stuff ...
+ callback(null, 'two');
+ }
+ ],
+ // optional callback
+ function(err, results) {
+ // results is now equal to ['one', 'two']
+ }
+);</code></pre>
+
+<h2 id="Các_hoạt_động_bất_đồng_bộ_phụ_thuộc_trong_chuỗi">Các hoạt động bất đồng bộ phụ thuộc trong chuỗi</h2>
+
+<p>Phương thức <code><a class="external external-icon" href="http://caolan.github.io/async/docs.html#waterfall" rel="noopener">async.waterfall()</a></code>này được sử dụng để chạy nhiều hoạt động bất đồng bộ theo thứ tự khi mỗi hoạt động phụ thuộc vào kết quả của hoạt động trước đó.</p>
+
+<p>Hàm gọi lại được gọi bởi mỗi hàm bất đồng bộ chứa <code>null</code>đối số đầu tiên và kết quả trong các đối số tiếp theo. Mỗi hàm trong chuỗi lấy các đối số kết quả của lần gọi lại trước đó làm tham số đầu tiên, và sau đó là một hàm gọi lại. Khi tất cả các hoạt động được hoàn thành, một cuộc gọi lại cuối cùng được gọi với kết quả của hoạt động cuối cùng. Cách làm việc này là rõ ràng hơn khi bạn xem xét các đoạn mã dưới đây (ví dụ này là từ <em>async</em> tài liệu):</p>
+
+<pre class="brush: js line-numbers language-js"><code class="language-js">async.waterfall([
+ function(callback) {
+ callback(null, 'one', 'two');
+ },
+ function(arg1, arg2, callback) {
+ // arg1 now equals 'one' and arg2 now equals 'two'
+ callback(null, 'three');
+ },
+ function(arg1, callback) {
+ // arg1 now equals 'three'
+ callback(null, 'done');
+ }
+], function (err, result) {
+ // result now equals 'done'
+}
+);</code></pre>
+
+<h2 id="Cài_đặt_bất_đồng_bộ">Cài đặt bất đồng bộ</h2>
+
+<p>Cài đặt mô-đun bất đồng bộ bằng cách sử dụng trình quản lý gói NPM để chúng tôi có thể sử dụng nó trong mã của chúng tôi. Bạn làm điều này theo cách thông thường, bằng cách mở một dấu nhắc trong thư mục gốc của dự án <em>LocalLibrary</em> và nhập vào lệnh sau đây:</p>
+
+<pre class="brush: bash line-numbers language-bash"><code class="language-bash">npm install async</code></pre>
+
+<h2 id="Bước_tiếp_theo">Bước tiếp theo</h2>
+
+<ul>
+ <li>Quay lại  <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Hướng dẫn Express Phần 5: Hiển thị dữ liệu thư viện</a> .</li>
+ <li>Chuyển đến phần con tiếp theo của Phần 5: <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Template_primer">Mẫu mồi</a> .</li>
+</ul>
diff --git a/files/vi/learn/server-side/express_nodejs/displaying_data/index.html b/files/vi/learn/server-side/express_nodejs/displaying_data/index.html
new file mode 100644
index 0000000000..bdbf433fc3
--- /dev/null
+++ b/files/vi/learn/server-side/express_nodejs/displaying_data/index.html
@@ -0,0 +1,98 @@
+---
+title: 'Express Tutorial Part 5: Displaying library data'
+slug: Learn/Server-side/Express_Nodejs/Displaying_data
+tags:
+ - Beginner
+ - Controller
+ - Express
+ - Learn
+ - NeedsTranslation
+ - Template
+ - TopicStub
+ - View
+ - nodejs
+ - pug
+translation_of: Learn/Server-side/Express_Nodejs/Displaying_data
+---
+<div>{{LearnSidebar}}</div>
+
+<div>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs/forms", "Learn/Server-side/Express_Nodejs")}}</div>
+
+<p class="summary">We're now ready to add the pages that display the <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">LocalLibrary</a> website books and other data. The pages will include a home page that shows how many records we have of each model type, and list and detail pages for all of our models. Along the way we'll gain practical experience in getting records from the database, and using templates.</p>
+
+<table class="learn-box standard-table">
+ <tbody>
+ <tr>
+ <th scope="row">Prerequisites:</th>
+ <td>Complete previous tutorial topics (including <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a>).</td>
+ </tr>
+ <tr>
+ <th scope="row">Objective:</th>
+ <td>To understand how to use the async module and Pug template language, and how to get data from the URL in our controller functions.</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Overview">Overview</h2>
+
+<p>In our previous tutorial articles we defined <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Mongoose models</a> that we can use to interact with a database and created some initial library records. We then <a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">created all the routes</a> needed for the LocalLibrary website, but with "dummy controller" functions (these are skeleton controller functions that just return a "not implemented" message when a page is accessed).</p>
+
+<p>The next step is to provide proper implementations for the pages that <em>display</em> our library information (we'll look at implementing pages featuring forms to create, update, or delete information in later articles). This includes updating the controller functions to fetch records using our models, and defining templates to display this information to users.</p>
+
+<p>We will start by providing overview/primer topics explaining how to manage asynchronous operations in controller functions and how to write templates using Pug. Then we'll provide implementations for each of our main "read only" pages with a brief explanation of any special or new features that they use.</p>
+
+<p>At the end of this article you should have a good end-to-end understanding of how routes, asynchronous functions, views, and models work in practice.</p>
+
+<h2 id="Displaying_library_data_tutorial_subarticles">Displaying library data tutorial subarticles</h2>
+
+<p>The following subarticles go through the process of adding the different features required for us to display the required website pages. You need to read and work through each one of these in turn, before moving on to the next one.</p>
+
+<ol>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/flow_control_using_async">Asynchronous flow control using async</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Template_primer">Template primer</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/LocalLibrary_base_template">The LocalLibrary base template</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Home_page">Home page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Book_list_page">Book list page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_list_page">BookInstance list page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Date_formatting_using_moment">Date formatting using moment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Author_list_page">Author list page and Genre list page challenge</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Genre_detail_page">Genre detail page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Book_detail_page">Book detail page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/Author_detail_page">Author detail page</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data/BookInstance_detail_page_and_challenge">BookInstance detail page and challenge</a></li>
+</ol>
+
+<h2 id="Summary">Summary</h2>
+
+<p>We've now created all the "read-only" pages for our site: a home page that displays counts of instances of each of our models, and list and detail pages for our books, book instances, authors, and genres. Along the way we've gained a lot of fundamental knowledge about controllers, managing flow control when using asynchronous operations, creating views using <em>Pug</em>, querying the database using our models, how to pass information to a template from your view, and how to create and extend templates. Those who completed the challenge will also have learned a little about date handling using <em>moment</em>.</p>
+
+<p>In our next article we'll build on our knowledge, creating HTML forms and form handling code to start modifying the data stored by the site.</p>
+
+<h2 id="See_also">See also</h2>
+
+<ul>
+ <li><a href="http://caolan.github.io/async/docs.html">Async module</a> (Async docs)</li>
+ <li><a href="https://expressjs.com/en/guide/using-template-engines.html">Using Template engines with Express</a> (Express docs)</li>
+ <li><a href="https://pugjs.org/api/getting-started.html">Pug</a> (Pug docs)</li>
+ <li><a href="http://momentjs.com/docs/">Moment</a> (Moment docs)</li>
+</ul>
+
+<p>{{PreviousMenuNext("Learn/Server-side/Express_Nodejs/routes", "Learn/Server-side/Express_Nodejs/forms", "Learn/Server-side/Express_Nodejs")}}</p>
+
+<p> </p>
+
+<h2 id="In_this_module">In this module</h2>
+
+<ul>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Introduction">Express/Node introduction</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/development_environment">Setting up a Node (Express) development environment</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Tutorial_local_library_website">Express Tutorial: The Local Library website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/skeleton_website">Express Tutorial Part 2: Creating a skeleton website</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/mongoose">Express Tutorial Part 3: Using a Database (with Mongoose)</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/routes">Express Tutorial Part 4: Routes and controllers</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/Displaying_data">Express Tutorial Part 5: Displaying library data</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/forms">Express Tutorial Part 6: Working with forms</a></li>
+ <li><a href="/en-US/docs/Learn/Server-side/Express_Nodejs/deployment">Express Tutorial Part 7: Deploying to production</a></li>
+</ul>
+
+<p> </p>