iT邦幫忙

2023 iThome 鐵人賽

DAY 26
0

技術筆記

如何寫promise?

const cart = ['apple', 'banana', 'carrot', 'onion']

//creatOrder, proceedToPayment, showOrderSummary, updateWallet
//延續同樣的例子

creatOrder(cart)
 .then(function (orderID) {
    //proceedToPayment(orderID)
    //目前還沒有寫到proceedToPayment函式,先comment
    //用console.log(orderID)測試
    console.log(orderID);
 })
  • creatOrder(cart)就是我們所創造的promise,其內容該怎麼寫?
    • 透過new Promise建立物件
    • 裡面需放一個函式,含有兩個參數resolve跟reject,分別表示成功及失敗的回傳結果,resolve跟reject可自訂名稱,但大部分開發者都直接沿用
const pr = new Promise(function (resolve, reject) {
	resolve() //成功的回傳結果
	reject() //失敗的回傳結果
})
  • 回到上面的範例
function creatOrder(cart) {
	const pr = new Promise(function (resolve, reject) {
		if (!validateOrder(cart)) {
			const err = new Error('the cart is not valid')
			reject(err)
		}
		const orderID = 's0001'
		resolve(orderID)
	})
	return (pr)
}

function validateOrder(cart) {
	return true
}

//s0001
  • 如果把validateOrder內容改為return false
    devtool會回傳以下訊息:
    https://ithelp.ithome.com.tw/upload/images/20231011/20163234k6Z1bGnABO.png
    但這個訊息僅止於瀏覽器內看見,使用者端完全不會有動靜,要讓錯誤訊息在使用者端跳出,要用catch
    creatOrder(cart)
      .then(function (orderID) {
       // proceedToPayment(orderID)
       console.log(orderID);
      })
      .catch(function (err) {
        console.log(err.message);
      })
    

此時devtool的回傳就可以看出已成功的把錯誤訊息傳達給使用者
https://ithelp.ithome.com.tw/upload/images/20231011/20163234Udn7vCfBz4.png

Promise chaining

  • 如果在createOrder之後,我們先印出orderID,之後進入proceedToPayment
  • 這次介紹另一個寫法,直接return new Promise
function proceedToPayment(orderID) {
		return new Promise(function (resolve, reject) {
			resolve('the payment is successful')
	})
}

  • 回到主程式,我們想在付款完,在使用者端回覆成功支付的訊息
creatOrder(cart)
	.then(function (orderID) {
		console.log(orderID);
		return orderID
	})
	.then(function (orderID) {
		return proceedToPayment(orderID)
	})
	.then(function (paymentInfo) {
    console.log(paymentInfo);
	})

devtool回傳
https://ithelp.ithome.com.tw/upload/images/20231011/20163234tyN7fEuw9Z.png

  • 主程式這一連串的then就是所謂的promise chaining
  • 相等於以下程式,但這種寫法就走向promise hell...程式很醜難讀難懂,那就枉費學promise了,所以千萬不要這樣寫
creatOrder(cart)
	.then(function (orderID) {
		console.log(orderID);
		return orderID
	})
	.then(function (orderID) {
		return proceedToPayment(orderID).then(function (paymentInfo) {
			console.log(paymentInfo);
		})
	})	

Error Handling

  • 也就是catch放的位置,catch可以掌握在它之上的所有錯誤回傳,假設放在最下面,那第一個then為失敗傳去catch回傳後,其下的其他then(即第二個then開始)都不會再執行
  • 再一次把validateOrder內容改為return false,devtool只會回傳錯誤訊息
creatOrder(cart)
	.then(function (orderID) {
		console.log(orderID);
		return orderID
	})
	.then(function (orderID) {
		return proceedToPayment(orderID)
	})
	.then(function (paymentInfo) {
		console.log(paymentInfo);
	})	
	.catch(function (err) {
		console.log(err.message);
	})
	

function creatOrder(cart) {
	const pr = new Promise(function (resolve, reject) {
		if (!validateOrder(cart)) {
			const err = new Error('the cart is not valid.')
			reject(err)
		}
		const orderID = 's0001'
		resolve(orderID)
	})
	return (pr)
}

function validateOrder(cart) {
	return false
}

function proceedToPayment(orderID) {
		return new Promise(function (resolve, reject) {
			resolve('the payment is successful')
	})
}

https://ithelp.ithome.com.tw/upload/images/20231011/20163234FCdpJKpDro.png

  • 如果我們把.catch移到第一個then後面
creatOrder(cart)
	.then(function (orderID) {
		console.log(orderID);
		return orderID
	})
	.catch(function (err) {
		console.log(err.message);
	})
	.then(function (orderID) {
		return proceedToPayment(orderID)
	})
	.then(function (paymentInfo) {
		console.log(paymentInfo);
	})	
	

https://ithelp.ithome.com.tw/upload/images/20231011/20163234kuLBpUa9NJ.png

  • catch之後的then還是可以被執行,所以devtool會印出之後的the payment is successful
  • 所以我們可以在特定then後面放要掌握它的catch,最後再加一個總管整個promise chaining的catch在最後,這就是我所理解的error handling

心得

promise真的要多練習幾次,光練習寫程式,卡住的次數完全數不清,花了一整天時間,影片來來回回,但越寫越有趣,而且寫出來的程式真的很簡潔美麗,真是個強大的語法。

參考資料

童言童語

努力看完天書後,來點輕鬆的吧!分享我兒子的童言童語,調劑身心一下

5歲樂咖+2歲嗨啾 = 我的神奇寶貝 皮咖啾

2021/03/13
咖:我聞到香味了
我:什麼香味?
咖:我肚子裡飲料的香味。
我:你那是打嗝吧⋯
咖:對啊!

還好沒說我也要聞

2021/03/12
咖:媽媽,我跟你合開一家公司
我:哇!什麼公司?
咖:巴士公司
我:好喔!我們去開巴士賺錢錢
咖:巴士公司需要很多巴士!
我:⋯

這是陷阱題嗎?


上一篇
Day25 Promise 上
下一篇
Day27 reduce()
系列文
豆芽班日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言