ES6語法——Promise

Promise
  • Promise是一種異步編程的解決方案
什麼是異步
  • 有一個步驟,A執行完再執行B
  • 在程序上怎麼實現A執行完再執行B呢,這個步驟有兩種方式,一種是回調方式,另一種事件觸發的方式
  • Promise是區別於以上兩種方式的
Promise的作用
  • 解決異步操作問題的
Promise的基本用法
{	
	//模擬es5中ajax請求
	//es5中回調解決異步場景
	let ajax = function(callback){
		console.log('執行');
		setTimeout(function(){
		//判斷回調是否存在,存在就執行下一步
			callback&&callback.call()
		},2000)
	};
	ajax(function(){console.log('timeout1')})
	//es5回調處理異步的場景
	//如果過程複雜,那就會有很多回調,回調使用很多,回調之間的順序問題,使得後期維護難以閱讀
}
{
	//Promise處理相同問題
	let ajax = function(){//注意這裏沒有傳遞參數
		console.log('執行2')//執行完後直接返回 new Promise()
		//返回對象,也就是Promise實例
		//Promise實例具有一個then的方法,也就是執行下一步的功能
		//怎麼去執行呢,有兩個參數resolve 、 reject
		return new Promise(function(resolve,reject){
			//resolve:要執行下一步的操作
			//reject:要中斷當前的操作
			//setTimeout 用於模擬通訊時間
			setTimeout(function(){
				resolve()
			},2000);
		})
	};
	//下面是使用
	ajax().then(function(){
	//ajax()執行之後是返回的是Promise實例,
	//Promise實例具有then方法(即下一步)
	//then參數就是這個函數體就是下一步
		console.log('promise','timeout2');
		//...這個函數體就是resolve
	},function(){//這個不調用可以不寫
		//...這個函數體就是reject
	})
}
//無註釋版
{
	let ajax = function(){
		return new Promise(function(resolve,reject){
			setTimeout(function(){
				resolve();
			},2000)
		})
	}
	ajax().then(function(){console.log('resolve')})
}
//多次回調
{
	let ajax = function(){
		console.log('then1')
		return new Promise(function(resolve,reject){
			setTimeout(function(){
				resolve();
			},2000)
		})
	}
	ajax()
	.then(function(){
		console.log('then2')
		return new Promise(function(resolve,reject){
			setTimeout(function(){
				resolve();
			},2000)
		})
	})
	.then(function(resolve,reject){
		console.log('then3')
		setTimeout(function(){
			resolve()
		},2000)
	})
}
//串型中出現錯誤如何捕獲錯誤
//catch
{
	let ajax = function(num){
		console.log('then1')
		return new Promise(function(resolve,reject){
			if(num>5){
				resolve();
			}else{
				throw new Error('出錯了')
			}
		})
	}
	ajax(4).then(function(){
		console.log('log',6);
	}).catch(function(error){//error參數就是捕獲錯誤
		console.log('catch',error)//catch Error: 出錯了
	})
}
Promise.all 、Promise.race 兩個方法的使用場景
  • 前端fade流
  • fade流內容會有多圖的形式,比三張圖加載,三張圖會有覆蓋廣告,一個個加載會有閃爍,用戶體驗不好,三張圖同時加載完再添加到頁面上,這樣用戶就看不到圖片加載的過程也看不到閃爍,不然加載三張圖的時間會有前有後,由於網絡延時,有些圖片加載成功,有些圖片加載失敗
  • 假設使用Promise,三張圖片全部加載成功之後再添加到頁面上,提高用戶體驗
//Promise.all()
{
	//所有圖片加載完再添加到頁面
	function loadImg(src){
	//loadImg函數返回Promise實例
	//使用異步的方式去加載圖片
		return new Promise((resolve,reject)=>{
			let img = document.createElement('img');
			img.src = src
			//img.onload監聽圖片是否加載完成
			img.onload = function(){
			//通過下一步的resolve傳遞參數
				resolve(img);
			}
			img.onerror = function(err){
				reject(err);
			}
		})
	}
	//加載完成之後添加到頁面上
	function showImgs(imgs){
		imgs.forEach(img=>document.body.appendChild(img));
	}
	//Promise.all 把多個Promise實例當作一個Promise實例
	//Promise.all([])是個數組,數組裏傳遞進來的是多個Promise實例
	//當所有Promise實例的狀態發生改變的時候,那麼新的Promise實例纔會發生變化
	//在這裏也就是說下面三個狀態全部完成之後,纔會觸發新的Promise對象,所有Promise對象纔有then的方法去執行showImgs
	//Promise.all返回的是一個Promise實例
	Promise.all([
		loadImg(''),//圖片地址
		loadImg(''),
		loadImg('')
	]).then(showImgs);
}
//Promise.race 有三張圖片,位於不同的位置,頁面需要加載一張圖片,我也不知道三張圖片哪個返回比較快,我不關心三張圖片來源,只要加載出一個就可以,先到先得。哪個到了就顯示哪個
{
	//有一個圖片加載完就添加到頁面
	function loadImg(src){
	//loadImg函數返回Promise實例
	//使用異步的方式去加載圖片
		return new Promise((resolve,reject)=>{
			let img = document.createElement('img');
			img.src = src
			//img.onload監聽圖片是否加載完成
			img.onload = function(){
			//通過下一步的resolve傳遞參數
				resolve(img);
			}
			img.onerror = function(err){
				reject(err);
			}
		})
	}
	function showImgs(img){
		let p = document.createElement('p');
		p.appendChild(img);
		document.body.appendChild(p);
	}
	//Promise.race中有一個率先改變,race就改變,就執行then(下一步)
	Promise.race([
		loadImg(''),//圖片地址
		loadImg(''),
		loadImg('')
	]).then(showImgs);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章