1. 程式人生 > >面試題之:Promise的前世今生

面試題之:Promise的前世今生

jquery中ajax的幾種方法如下:

	// 方案1
    var ajax = $.ajax({
      url: './1.json',
      success: function() {
        console.log(1);
        console.log(2);
        console.log(3);
      },
      error: function() {
        console.log('err')
      }
    })
    // 方案2
    var ajax = $.ajax('./1.json');
    ajax.
done(function() { console.log('done1') }).fail(function() { console.log('fail1') }).done(function() { console.log('done2') }).fail(function() { console.log('fail1') }).done(function() { console.log('done3') }).fail(function() { console.log('fail1'
) }) // 方案3 var ajax = $.ajax('./1.json'); ajax.then(function() { console.log('then1') }, function() { console.log('catch1') }).then(function() { console.log('then2') }, function() { console.log('catch1') }).then(function() { console.log('then3'
) }, function() { console.log('catch1') })

jquery中的promise雛形: Deferred

以上都是靠Deferred實現的。那麼deferred到底是個什麼東西呢?如何考deferred來結局非同步呢?

  1. 宣告一個函式
  2. 宣告一個$.deferred例項
  3. 宣告一個wait函式,傳入dtd,對dtd進行操作
  4. 把dtdreturn出來

具體程式碼如下:

var waitHandle = function() {
	var dtd = $.Deferred();
	var wait = function(dtd) {
		setTimeout(function() {
			console.log('執行完成')
			dtd.resolve() //執行成功的回撥
			dtd.reject() //執行失敗的回撥
		}, 1000)
	}
	return dtd.promise()
}

var w = waitHandle()

$.when(w).then(function() {
	//執行成功的函式
}, function() {
	//執行失敗的回撥函式
})

注意點:

  1. promise和deferred的區別是: promise把resolve和reject在函式外部過濾了。
  2. dtd.resolve 和dtd.reject() 同時只能執行1個

規範化: promise

基本語法

function loadImg(src) {
	const promise = new Promise((resolve, reject) => {
		var img = document.createElement('img')
		img.onload = function() {
			resolve(img)
		}
		img.onerror = function() {
			reject()
		}
		img.src = src
	})
	return promise
}
var src = "xxx"
var result = loadImg(src)
result.then(function(img) {
	console.log(img.width)
}, function() {
	console.log("faild")
})
result.then(function(img) {
	console.log("height")
})

非同步語法

result.then(function() {
	//程式碼
}).then(function() {
	//程式碼
}).catch(function(ex) {
	//統一處理錯誤
	console.log(ex)
})

串聯執行

加入有兩個ajax請求,一個請求要在另外一個請求之後執行應該怎麼處理?
在第一個要執行的promise裡面返回第二個promise。
程式碼如下:

function loadImg(src) {
	const promise = new Promise((resolve, reject) => {
		var img = document.createElement('img')
		img.onload = function() {
			resolve(img)
		}
		img.onerroe = function() {
			reject()
		}
		img.src = src
	})
	return promise
}

//呼叫promise函式

var src1 = "...png"
var result1 = loadImg(src1)
var src2 = "...jpg"
var result2 = loadImg(src2)

result1.then(function() {
//result1的回撥函式
	console.log('圖片1執行成功')
	return result2
}).then(function() {
//result2的回撥函式
	console.log('圖片2執行成功')
}).catch() {
	console.log('error')
}
	

promise.all && promise.race

  1. promise.all 和 promise.race 都接受一個promise的陣列
  2. all 是所有的promise都執行完了才then
  3. race 是隻要有一個promise執行完成了就執行then
  4. all 返回一個datas的陣列,是所有promise返回的集合
  5. race 返回data是第一個執行的Promise的結果

程式碼如下:

Promise.all([ promise1, promise2]).then(function(datas) {
	console.log(datas[1])
	console.log(datas[2])
})
Promise.race([promise1, promise2]).then((data) => {
	console.log(data)
})

promise標準

任何技術推廣都需要一套標準來支撐

promise的狀態

  1. pending 初始狀態
  2. fulfilled 成功狀態
  3. rejected 失敗狀態

promise的then

  1. 必須執行
  2. 接受兩個引數
  3. 返回的必須是一個promise例項
  4. 如果沒有返回值,返回的就是promise本身的例項