首頁  >  文章  >  web前端  >  JS 中的非同步和 Promise 解釋

JS 中的非同步和 Promise 解釋

WBOY
WBOY原創
2024-09-04 07:03:06685瀏覽

async and promises explained in JS

注意:所有概念都是相互關聯的,因此要了解一件事,您還需要了解其他概念

阻止程式碼

假設您的程式中有需要數年時間才能完成的循環。現在你有兩個選擇,要嘛繼續前進,要嘛等待。如果您選擇等待,那麼它將被視為阻塞代碼。如果沒有那麼你就沒有選擇了?讓我們看看。

//blocking code
let sum = 0;
for(let i = 1;i<Number.MAX_SAFE_INTEGER;i++){
  for(let j = 1;j<Number.MAX_SAFE_INTEGER;j++){
      sum = i+j;
}
}
console.log(sum);
// above program is dummy and does not serve any purpose

現在,如您所見,在完成之前不會讓運行低於它的程式。現在要運行總和,我們必須等待數年,用戶可能會錯過一些重要的事情(其他功能)。

為了繞過這種情況,我們可以將 for 和 console.log(sum) 放入某個可以與我們的程式碼並行運行的檔案中,並等到我們給它一個綠燈。這稱為異步。非同步程式碼與主程式碼並行運行,並且僅在主程式碼完成後運行。

如果非同步程式碼中有另一個非同步程式碼。直到外部完成後才會運作。

作業問題

以下程式的輸出為何?

  • setInterval是一個內建的JS函數,用來間隔運行程式。
// will inner ever run ? if yes then why (ask gemini/gpt)
setInterval(()=>{
  console.log("outer");
  setInterval(()=>{
    console.log("inner");
  },1000)
},1000)

非阻塞程式碼

setTimeout(()=>{
   console.log("outer");
   setTimeout(()=>{
     console.log("inner");
     for(let i = 1;i<1000;i++){}
     console.log("inner finished");
   },0)
   console.log("outer finishes");
},0)
console.log("i will run first");

輸出

i will run first
outer
outer finishes
inner
inner finished

注意:從上面的程式碼中,您可以發現外部區塊現在充當主程式碼,而內部區塊充當非同步程式碼。

你甚至會看到console.log(“i will run first”)寫在它首先運行的主程式碼之後。如何 ?這稱為非阻塞或非同步程式碼。它不會妨礙程式的主要功能。讓您在應用程式中進行寫入和讀取等操作。

非同步等待

await 關鍵字始終包含在非同步函數中,並且在完成之前不會讓其下面的其他程式碼執行。 async 和await 是金鑰對。另一件事是,await 總是放在傳回 Promise 的函數之前,並且總是將其包裝在 try catch 區塊中。

async function myPromise(){
 try{
  await doSomething(); // a function that return promise
  console.log("Your file is successfully created"); //only runs when promise is accepted
  }
  catch(err){
   console.log(err); // if promised is rejected;
  }
}
myPromise();
console.log("first");

輸出

# consider promise to be successful
first
Your file is successfully created

到目前為止的理解(結論):

  1. 函數傳回的 Promise 總是封裝在 async-await 中。
  2. async-await 齊頭並進。
  3. 始終將await 包裹在try-catch 區塊中。 (如果沒有請參考我的部落格)
  4. 現在,非同步函數之外的程式將始終運行,無論它是否已解決或拒絕,如上所示。 (這就是美麗?)
  5. 現在讓我們來了解承諾

現在讓我們從 Promise 的應用程式開始

  1. API 請求 - 從另一台伺服器取得資料
  2. 檔案操作 - 讀寫檔案
  3. 資料庫查詢 - 取得或寫入資料

您是否在所有用例中發現了一些共同點?

是的,所有應用程式都需要時間來執行。

Promise 賦予我們超能力來充分處理這種情況。再次,Promise 和 async-await 齊頭並進。

Promise 有 3 種狀態(如上例所示)

  • 已解決(如果是這樣那麼我們的檔案建立成功就會運行)
  • 被拒絕(catch 區塊中的程式碼將運行)
  • 待處理(它將等待並且不會讓任何程式碼在函數內運行)

讓我們在 JS 中建立一個自訂的 Promise

傳回 Promise 的函數外部的 async 關鍵字純粹是可選的。請參閱下面的程式碼...

取得數據

// trying to mimic as a server response
function fetchData(success=false){
  return new Promise((resolve,reject)=>{
    if(success){
      setTimeout(()=>{
        resolve("fetched successfully");
      },5000) // execute after 5 sec
    }
    else
    reject("server is not responding");
  })
}
// lets consider fetchData is in-built function

主要

/* lets consider fetchData is a in-built function that gets data from other server. We are passing success para to just mimic the server otherwise it does not serve any purpose here.
*/
async function getData(){
  try{
    let result = await fetchData(true);
    console.log(result) //fetched successfully
  }
  catch(err){
    console.log(err); // in case of rejection
  }
}
getData();
// load other code

無論是否取得數據,其他程式碼也會運作。它提高了性能並提高了我們程式碼的品質。

參考

aryan 的錯誤處理

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

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