😅Sử dụng async, await, bất đồng bộ lấy dữ liệu Pagination, sử dụng Deferred 👌 phần 2 (ok)

https://stackoverflow.com/questions/23355168/jquery-recursive-ajax-call-promise

ajax.php

<?php
$products = array(
  array(
    'id' => '1',
    'title' => 'Product 1',
    'sku' => 'code-2',
    'price' => '95.00',
    'category' => 'Shirts',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '2',
    'title' => 'Product 2',
    'sku' => 'code-2',
    'price' => '145.00',
    'category' => 'Pants',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '3',
    'title' => 'Product 3',
    'sku' => 'code-3',
    'price' => '895.00',
    'category' => 'Shirts',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '4',
    'title' => 'Product 4',
    'sku' => 'code-4',
    'price' => '295.00',
    'category' => 'Pants',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '5',
    'title' => 'Product 5',
    'sku' => 'code-5',
    'price' => '215.00',
    'category' => 'Caps',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '6',
    'title' => 'Product 6',
    'sku' => 'code-6',
    'price' => '365.00',
    'category' => 'Shirts',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '7',
    'title' => 'Product 7',
    'sku' => 'code-7',
    'price' => '95.00',
    'category' => 'Caps',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '8',
    'title' => 'Product 8',
    'sku' => 'code-8',
    'price' => '495.00',
    'category' => 'Caps',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
  array(
    'id' => '9',
    'title' => 'Product 9',
    'sku' => 'code-9',
    'price' => '95.00',
    'category' => 'Caps',
    'image' => 'https://via.placeholder.com/500x300.png'
  ),
);
// Declare $filtered_products array to store products in the filter $_GET params
$filtered_products = array();
// Declare $categories array to store categories
$categories = array();
// Loop through products and store categories into categories array. Also store filtered products into an array
foreach ($products as $product) {
  // Make sure item has a category key and a value, assigned as key and value to prevent duplicates
  if ($product['category'] && !empty($product['category'])) {
    $categories[$product['category']] = $product['category'];
  }
  //Store filtered products if set
  if (isset($_GET['category']) && !empty($_GET['category']) && $product['category'] == $_GET['category']) {
    $filtered_products[] = $product;
  }
}
// Get the total products based on filter must come AFTER the loop above
$total_products = isset($_GET['category']) && !empty($_GET['category']) ? count($filtered_products) : count($products);
// Declare a variable for our current page. If no page is set, the default is page 1
$current_page = isset($_GET['page']) ? $_GET['page'] : 1;
// Declare $limit value this can either be another filter option, a value pulled from the database (like user preferences) or a fixed value
$limit = 2;
// Declare an offset based on our current page (if we're not on page 1).
if (!empty($current_page) && $current_page > 1) {
  $offset = ($current_page * $limit) - $limit;
  /*
  for example, if we are on page 3 and we're only showing 2 items per page, we've already seen four items, two on page 1 and two on page 2. So our next number should be 5.
  We need to offset by 4.
  (3 * 2) - 2
  3 * 2 = 6, 6 - 2 = 4 (so we offset the value by 4 )
  */
} else {
  $offset = 0;
}
// Get the total pages rounded up the nearest whole number
$total_pages = ceil($total_products / $limit);
// Declare active category filter to use when we paginate so we don't lose the filter
$filtered_category_query = isset($_GET['category']) ? '&category=' . $_GET['category'] : '';
// When we filter, we want to know the range of products we're viewing
$first_product_displayed = $offset + 1;
//example : if we're on page 3, our offset is 4 ( limit(page 1) + limit(page2) ) so 4 + 1 = 5 (first product in view is 5)
// if the total products is more than the current offset x 2 + 2 then our last product is the offset + 2 or else it should be the total
$last_product_displayed = $total_products >= ($offset * $limit) + $limit ? $offset + $limit : $total_products;
// example 1 : if we're on page 3, our offset is 4 ( limit(page 1) + limit(page2) ) so 4 x 2 = 8, + 2 = 10 (last product in view is 10)
// example 2 : if we're on page 2, our offset is 2 ( limit(page 2) ) so 2 x 2 = 4, + 2 = 6 (last product in view is 6)
// Display the current range in view
if ($first_product_displayed === $last_product_displayed) {
  $range = 'the Last of ' . $total_products . ' Products';
} else {
  $range = $first_product_displayed . ' - ' . $last_product_displayed . ' of ' . $total_products . ' Products';
}
?>
<?php
// Redefine $products array if there are filters set
if (isset($_GET['category']) && !empty($_GET['category'])) {
  // Array Slice allows us to offset and limit array output
  $products = array_slice($filtered_products, $offset, $limit);
}
// or leave as is
else {
  $products = array_slice($products, $offset, $limit);
}
// Loop through $products array
echo json_encode($products);
?>

index.php

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <meta name="description" content="">
  <meta name="author" content="">
  <title>Blog Home - Start Bootstrap Template</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.0/dist/css/bootstrap.min.css">
  <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
</head>
<body>
  <script type="text/javascript">
    function fetch(opt_offset,opt_result,defer) {
      var offset = opt_offset || 1;
      var result = opt_result || [];
      return $.ajax({
        url: 'https://lva.com/ajax.php?page=' + offset,
        type: 'GET',
        dataType: 'json',
        success: function(response) {
          result = result.concat(response);
          if(response.length == 2) {
            fetch(offset+1,result,defer);
          }else {
            defer.resolve(result);
          }
        }
      });
    }
    function requestAll(){
      var deferred = jQuery.Deferred();
      fetch(null, [], deferred);
      return deferred.promise();
    }
    requestAll().done(function(items) {
      console.log(items);
    });
  </script>
</body>
</html>

Last updated