Promise
Promise 對象是由關鍵字 new 及其構造函數來創建的。一共有三種狀態,分別爲pending
(進行中)、fulfilled
(已成功)和rejected
(已失敗)。創建示例如下:
const promise = new Promise((resolve, reject) => {
// do something here ...
if (success) {
resolve(value); // fulfilled
} else {
reject(error); // rejected
}
});
由上述代碼我們可知:
該構造函數接收兩個函數作爲參數,分別是resolve
和reject
。
當異步操作執行成功後,會將異步操作結果作爲參數傳入resolve
函數並執行,此時 Promise
對象狀態從pending
變爲fulfilled
;
失敗則會將異步操作的錯誤作爲參數傳入reject
函數並執行,此時 Promise
對象狀態從pending
變爲rejected
;
接下來,通過then
方法,分別指定resolved狀態和rejected狀態的回調函數。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then
方法可以接收兩個回調函數作爲參數,第一個回調函數就是fulfilled
狀態時調用;第二個回調函數就是rejected
時調用。這邊的第二個參數是可選的,不一定要提供。
Promise鏈式寫法:
const setDelaySecond = (seconds) => {
return new Promise((resolve, reject)=>{
if (typeof seconds != 'number' || seconds > 10) reject(new Error('參數必須是number類型,並且小於等於10'));
setTimeout(()=> {
resolve(`我延遲了${seconds}秒後輸出的,是第二個函數`)
}, seconds * 1000)
})
}
setDelay(2000)
.then((result)=>{
console.log(result)
console.log('我進行到第一步的');
return setDelaySecond(3)
})
.then((result)=>{
console.log('我進行到第二步的');
console.log(result);
}).catch((err)=>{
console.log(err);
})
Async/await
async/await是一對好基友,缺一不可,他們的出生是爲Promise服務的。可以說async/await是Promise的爸爸,進化版。
async聲明的函數的返回本質上是一個Promise。
什麼意思呢?就是說你只要聲明瞭這個函數是async
,那麼內部不管你怎麼處理,它的返回肯定是個Promise。
看下列例子:
(async function () {
return '我是Promise'
})()
// 返回是Promise
//Promise {<resolved>: "我是Promise"}
所以你想像一般function
的返回那樣,拿到返回值,原來的思維要改改了!你可以這樣拿到返回值:
const demo = async function () {
return Promise.resolve('我是Promise');
// 等同於 return '我是Promise'
// 等同於 return new Promise((resolve,reject)=>{ resolve('我是Promise') })
}
demo.then(result=>{
console.log(result) // 這裏拿到返回值
})
上述三種寫法都行,要像對待Promise一樣去對待async的返回值。
注意:await 命令後面的 Promise 對象,運行結果可能是 rejected,所以最好把 await 命令放在 try...catch 代碼塊中。
async function myFunction() {
try {
await somethingThatReturnsAPromise();
} catch (err) {
console.log(err);
}
}
// 另一種寫法
async function myFunction() {
await somethingThatReturnsAPromise().catch(function (err){
console.log(err);
});
}
await 命令只能用在 async 函數之中,如果用在普通函數,就會報錯。
async function dbFuc(db) { let docs = [{}, {}, {}]; // 報錯 docs.forEach(function (doc) { await db.post(doc); }); }