用最簡單的例子講解js中解決非同步的方法

蘭村_web發表於2020-11-22

解決js非同步的方法有很多中,今天就講解一下如何解決js中的非同步問題。

在講解非同步解決辦法之前我們需要知道什麼是非同步。定時器、AJAX、事件繫結等都會引起js的非同步行為,今天用js中的定時器為例來講解,看下題。

考慮下題中輸出的結果為:

    function getData() {
		setTimeout(function() {
			let name = '張三';
			return name;
		}, 1000);
	}
	console.log(getData());

這裡就有很多人會說輸出的結果為張三,那就說明你還沒有真正理解非同步。其實真正的輸出結果為:undefined。這是因為setTimeout方法為非同步方法。如果不明白為什麼會這樣,這裡我講一下js的執行機制大家就會更加明白了。

js執行機制:
(1).所有同步任務都在主執行緒上執行,形成一個執行棧(execution context stack);
(2).主執行緒之外,還存在一個"任務佇列"(task queue),只要非同步任務有了執行結果,就在"任務佇列"之中放置一個事件;
(3).一旦"執行棧"中的所有同步任務執行完畢,系統就會讀取"任務佇列",看看裡面有哪些事件,那些對應的非同步任務,於是結束等待狀態,進入執行棧,開始執行;
(4).主執行緒不斷重複上面的第三步;

解決非同步的方法一(回撥函式):

  function getData(callback) {
  	setTimeout(function() {
  		let name = '張三';
  		callback(name);
  	}, 1000);
  }
  getData(function(aaa){
    console.log(aaa); //等待一秒之後輸出 張三
  })

解決非同步的方法二(es6的Promise):

function getData(resolve, reject){
    setTimeout(function() {
		var name="張三";
		resolve(name);
	}, 1000);
};

var p = new Promise(getData);
p.then(function(data){
	console.log(data);//等待一秒之後輸出 張三
})

解決非同步的方法三(es7的async/await):
async用於申明一個非同步的function,而await用於等待一個非同步方法執行完成。

   async function getData(){ //通過async封裝非同步方法
	   return new Promise((resolve, reject) => {
			setTimeout(function() {
				var name = '張三';
				resolve(name);
			}, 1000);
		})
	}
		
    async function main(){
		var data = await getData();
		console.log(data);//等待一秒之後輸出 張三
	}
	main();

以上就是處理非同步最常用的三種方法,不過第一種的回撥函式方法是es6之前的處理方法,容易造成回撥地獄,不易維護,不建議過多使用。

相關文章