異步是JavaScript中非常重要的一個概念,它可以使得我們的代碼更加高效、優美。在講異步之前,我們先來看一下同步代碼。在JavaScript中,同步代碼就是一個操作需要等待前一個操作完成才能進行,例如:
let num1 = 10; let num2 = 5; let sum = num1 + num2; console.log(sum);
上面的代碼是同步代碼,因為num2需要等待num1賦值后才能與num1進行相加操作,sum需要等待num1和num2相加完成后才能賦值。
如果我們需要進行一些比較耗時的操作,比如發送AJAX請求、讀寫文件等等,同步代碼的方式就非常低效,因為需要等待前一個操作完成才能進行下一個操作,導致代碼執行時間非常長。
這個時候就需要使用異步操作了,異步代碼可以在執行一個操作時同時進行其他操作,等待操作完成后再返回執行后續代碼。最常用的異步操作方式是回調函數。
回調函數是一種函數,在異步操作完成后運行,通常會在異步函數的參數中傳遞。當異步操作完成后,回調函數會執行,將結果傳遞回給異步操作的調用方。下面是一個發送AJAX請求的例子:
function getJSON(url, callback) { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { const data = JSON.parse(xhr.responseText); callback(data); } } xhr.open('GET', url, true); xhr.send(); } getJSON('https://jsonplaceholder.typicode.com/posts/1', function(data) { console.log(data); });
在上面的例子中,getJSON函數是一個異步函數,它接收一個callback參數,這個參數就是一個回調函數。當AJAX請求完成后,回調函數會執行,將data作為參數傳遞進去。
除了回調函數之外,JavaScript還提供了其他一些異步操作方式,比如Promise、async/await等等。
Promise是ES6中新增的一種異步操作方式,它是一個對象,可以包含異步操作成功或失敗的情況。下面是一個Promise的例子:
function getJSON(url) { return new Promise(function(resolve, reject) { const xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)); } else { reject(xhr.statusText); } } }; xhr.open('GET', url, true); xhr.send(); }); } getJSON('https://jsonplaceholder.typicode.com/posts/1') .then(function(data) { console.log(data); }) .catch(function(err) { console.log(err); });
上面的代碼中,getJSON函數返回一個Promise對象,當AJAX請求完成后,resolve或reject會被調用,將結果傳遞給.then或.catch中的回調函數。
最后,我們再來看一下async/await這種異步操作方式。async/await是ES8中引入的,它是基于Promise實現的一種語法糖。async表示該函數中有異步操作,await表示等待異步操作完成。下面是一個async/await的例子:
function delay(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } async function foo() { console.log('start'); await delay(1000); console.log('end'); } foo();
上面的代碼中,foo函數中使用了await,等待delay函數完成后再執行后續代碼,因此會輸出start和end之間隔了1秒的時間。
以上就是JavaScript中異步操作的幾種方式,它們可以使我們的代碼更加高效、優美,更好地應對一些比較耗時的操作。