首頁  >  文章  >  web前端  >  了解異步 JS

了解異步 JS

王林
王林原創
2024-09-01 21:07:111021瀏覽

Understanding Async JS

Async JS 的目標:處理在背景運行的長時間運行的任務

  • 用例:透過 AJAX 呼叫從遠端伺服器取得資料。
  • 例如。設定影像來源、定時器、Promises、Fetch API、Async-Await、Geolocation API、Error-Handling。

同步程式碼:

  • 依序逐行執行,其中由作為執行上下文一部分的執行緒寫入。
  • Dis:當一行程式碼需要很長時間才能執行,例如 AJAX 呼叫、D/b 存取、警報視窗等,這會阻塞程式碼執行直到完成。

非同步程式碼

  • 計時器在背景執行,不會阻塞程式碼,也就是不會阻塞執行的主執行緒。
  • 後台運行的任務完成後執行非同步程式碼。
  • 執行不會等待非同步任務完成其工作。
  • 非同步 - 不同時發生。
  • 回呼不會使程式碼自動非同步。前任。數組映射方法接受回調,但它不會使程式碼非同步。只有某些函數(例如計時器)以非同步方式運作,但並非所有回呼。
const p = document.querySelector('.p');
setTimeout(function(){
  p.textContent = "Welcome to JS";
}, 3000); // C/b executes after duration.
p.style.color = 'red';
Ex. Setting source of an img is an async operation, while rest of the code is running. Once the image is loaded completely, a load event will be emitted by JS for which we can listen.

const img = document.querySelector('.cat');
img.src = 'cat.jpg'
img.addEventListener('load',function(){
  img.classList('fadeIn');
});
p.style.width = '300px';
  • 單獨的事件監聽器不會使程式碼非同步。例如,按鈕按一下偵聽器不在背景執行任何工作。因此,不涉及異步行為。

阿賈克斯

  • 允許我們以非同步方式與遠端 Web 伺服器通訊。
  • 使用 AJAX 呼叫動態地從 Web 伺服器請求資料。

應用程式介面

  • 另一個軟體使用的軟體,可實現黑白應用程式的通訊。
  • 例如。 DOM API、Geoloaction API 等都是獨立的軟體,允許軟體與它們互動
  • 我們可以透過使用類別並公開一些方法來實作 API。
  • 線上 API:在伺服器上運行的應用程序,接收資料請求,並發送回資料作為回應。
  • API 是使用後端開發建置的或使用其他開發人員免費提供給我們的第 3 方 API。
  • 例如。幾乎所有內容都有範例 API。
  • 之前使用的是XML,現在只使用JSON,也就是JS物件轉換為字串。
# First API Call: Older way of doing AJAX using XHR. Modern way uses fetch API.
- CORS need to be Yes/Unknown to access 3rd party APIs from our code.
- AJAX call is done in the background, while the rest of the code keeps running which makes it non-blocking.
- Hence, register a callback for the load event on request object.
- Request is sent in the background, when its complete 'load' event will be fired. As soon data arrives, Callback fn will be called.

HTML:
<main class="container">
  <div class="countries">
</div>
</main>

JS:
const getCountryData = function(country){
const btn = document.querySelector('.btn-country');
const countriesContainer = document.querySelector('.countries');

// 1. request created
const request = new XMLHttpRequest(); 
// 2.request opened
request.open("GET", `https://restcountries.com/v3.1/name/${country}`); 
// 3. request sent
request.send();

// 4. When data arrives, load event will be fired & below C/b will be invoked.
// 5. response arrives in the property responseText of request object in JSON i.e big string of text will be received from AJAX call which needs to be converted to JS object.
// 6. Convert JSON to JS.
request.addEventListener("load", function () {
  // console.log(this);    this refers to request object here. 'this' can be replaced with request object.
  // console.log(this.responseText);  will only be set when data has arrived.

  // Both lines yield same result below.
  //const [ data ] = JSON.parse(this.responseText);
  const data = JSON.parse(this.responseText)[0];
  console.log(data);

  const html = `<article class="country">
  <img src=${data.flags.svg} alt="" class="country__img">
  <div class="country__data">
    <h3 class="country__name">${data.name.common}</h3>
    <h4 class="country__region">${data.region}</h4>
    <p class="country__row"><span>${(+data.population / 1000000).toFixed(1)}</span> mn</p>
    <p class="country__row"><span>${data.languages[Object.keys(data.languages)[0]]}</span></p>
    <p class="country__row"><span>${data.currencies[Object.keys(data.currencies)[0]].name}</span></p>
  </div>
</article>`;
  countriesContainer.insertAdjacentHTML('beforeend', html);
  countriesContainer.style.opacity = 1;
});
};

// All AJAX calls are happening in parallel
getCountryData('usa');
getCountryData('russia');
getCountryData('germany');
getCountryData('brazil');
getCountryData('india');

回調地獄:

  • 連結 AJAX 請求將使它們按順序工作,即第一個請求完成後將產生第二個請求。

- 由於需要按順序進行的巢狀 AJAX 呼叫定義的巢狀回調而導致。

// This below triangular shape denotes callback hell. Makes code hard to maintain.
// GPP: Code which is hard to understand is bad code, hence difficult to add features
// Promises help us to resolve this Callback Hell problem.

setTimeout(() => {
  console.log("1 sec passed");
  setTimeout(() => {
    console.log("2 sec passed");
    setTimeout(() => {
      console.log("3 sec passed");
      setTimeout(() => {
        console.log("4 sec passed");
        setTimeout(() => {
          console.log("5 sec passed");
          }, 1000);
        }, 1000);
      }, 1000);
    }, 1000); 
}, 1000);



// Get the neighbouring countries
const renderCountry = function (data) {
  const btn = document.querySelector(".btn-country");
  const countriesContainer = document.querySelector(".countries");

  const html = `<article class="country">
  <img src=${data.flags.svg} alt="" class="country__img">
  <div class="country__data">
    <h3 class="country__name">${data.name.common}</h3>
    <h4 class="country__region">${data.region}</h4>
    <p class="country__row"><span>${(+data.population / 1000000).toFixed(
      1
    )}</span> mn</p>
    <p class="country__row"><span>${
      data.languages[Object.keys(data.languages)[0]]
    }</span></p>
    <p class="country__row"><span>${
      data.currencies[Object.keys(data.currencies)[0]].name
    }</span></p>
  </div>
</article>`;
  countriesContainer.insertAdjacentHTML("beforeend", html);
  countriesContainer.style.opacity = 1;
};

const getNeighbours = function (country) {
  const request = new XMLHttpRequest();
  request.open("GET", `https://restcountries.com/v3.1/name/${country}`);
  request.send();

  request.addEventListener("load", function () {
    const [data] = JSON.parse(this.responseText);
    console.log(data);
    renderCountry(data);

    const [neightbour] = data.borders;
    if(!neightbour) return;

    // request2 is Dependent on request1 as its invoke after request1. request2 will its own event listener.
    const request2 = new XMLHttpRequest();
    request2.open("GET", `https://restcountries.com/v3.1/alpha/${data.borders}`);
    request2.send();

    request2.addEventListener("load", function () {
    const [data2] = JSON.parse(this.responseText);
    console.log(data2);
    renderCountry(data2);
  });
};

getNeighbours("italy");

以上是了解異步 JS的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn