js面試,異步和單線程相關問題

js面試,異步和單線程相關問題

一、異步
1.1
在js引擎是基於單線程的,因此在js引擎中,同一時刻只能執行一個代碼塊。需要即將運行的代碼都會被放在一個任務隊列中,每當一段代碼執行時,都會被放在一個任務隊列當中。

js中異步和同步可以這麼理解:程序先按順序執行同步代碼,然後按順序執行異步代碼(一般是ajax請求,事件事件就不是按順序了,你發起什麼事件,就響應什麼函數),所以同步會發生程序阻塞,而異步不會

1.2 前端中異步的使用

  • 定時任務:setTimeout,setInteveral
  • 網絡請求:ajax請求,動態的<img>加載

看下面這段代碼:

console.log(100);
setTimeout(()=>{
	console.log(200);
},1000)
console.log(300);//先100,在300,最後1s之後打印200

1.3同步和異步的區別

  • 同步會阻塞代碼的執行而異步不會
  • 比如alert就是同步,他會阻塞代碼的執行,而setTimeout是異步,因此不會阻塞代碼的執行。

二、Promise與異步
上面還只是關於es5異步的粗淺知識點,接來便進入es6的Promise與異步。

所謂Promise,簡單說就是一個容器,裏面保存着某個未來纔會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理。(截取es6教程)

2.1
Promise對象代表一個異步操作,有三種狀態:

  • pending(進行中)
  • fulfilled(已成功)
  • rejected(已失敗)

2.2
Promise特點(截取es6教程)

  • 對象的狀態不受外界影響。Promise對象代表一個異步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操作的結果,可以決定當前是哪一種狀態,任何其他操作都無法改變這個狀態。
  • 一旦狀態改變,就不會再變,任何時候都可以得到這個結果。Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。只要這兩種情況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱爲 resolved(已定型)。如果改變已經發生了,你再對Promise對象添加回調函數,也會立即得到這個結果。
const promise = new Promise(function(resolve, reject) {
  if (/* 異步操作成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});

Promise構造函數接受一個函數作爲參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用自己部署。

resolve函數的作用是,將Promise對象的狀態從“未完成”變爲“成功”(即從 pending 變爲 resolved),在異步操作成功時調用,並將異步操作的結果,作爲參數傳遞出去;reject函數的作用是,將Promise對象的狀態從“未完成”變爲“失敗”(即從 pending 變爲 rejected),在異步操作失敗時調用,並將異步操作報出的錯誤,作爲參數傳遞出去。

Promise實例生成以後,可以用then方法分別指定resolved狀態和rejected狀態的回調函數。

promise.then(function(value) {
  // success
}, function(error) {
  // failure
});

給個簡單的列子

function report(value){
	console.log(value)
}
var a = new Promise((resolve,reject)=>{
	report("reportA");
	setTimeout(()=>{
		let i = 1;
		report("reportB");
		if(i>1){
			resolve("hattori")//意思就是當i>1,“承若”實現,進行reolve
		}else{
			reject('rejectxx')//當i>,"承若"未實現,進行reject
		}
	},1000);
});
a.then((value)=>{
	console.log(value)
},(value)=>{
	console.log(value,'error')
})

打印結果是reportA reportB rejectxx error;
若改動將if裏的i=2;那麼 會打印reportA reportB hattori;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章