回調(diào)函數(shù)
- 回調(diào)函數(shù)分為兩種類型,分別為同步回調(diào)與異步回調(diào);
- 同步回調(diào):會立即執(zhí)行,完全執(zhí)行完了才結(jié)束,不會放入回調(diào)隊列中;
- 異步回調(diào):不會立即執(zhí)行,會放入回調(diào)隊列中 將來執(zhí)行;
<script>
//同步回調(diào)
const arr = [1, 3, 5];
arr.forEach((item) => {
console.log(item);
});
console.log('forEach(之后)');
//異步回調(diào)
setTimeout(() => {
console.log('異步回調(diào)');
}, 0);
console.log('setTimeout()之后');
</script>
- 遍歷回調(diào)屬于同步回調(diào),立即執(zhí)行;
- 定時器中的回調(diào)屬于異步回調(diào),不會立即執(zhí)行;
常見的內(nèi)置錯誤
- Error:所有錯誤的父類型;
- ReferenceError:引用變量不存在;
- TypeError:數(shù)據(jù)類型不正確;
- RangeError:數(shù)據(jù)值不在其所允許的范圍之內(nèi);
- SyntaxError:語法錯誤;
<script>
//1.ReferenceError:引用變量不存在
console.log(a); //ReferenceError: a is not defined
//2.TypeError:數(shù)據(jù)類型不正確
let b = {};
b.xxx(); //TypeError: b.xxx is not a function
//3.RangeError:數(shù)據(jù)值不在其所允許的范圍之內(nèi)
function func() {
func()
}
func(); //RangeError: Maximum call stack size exceeded
//4.SyntaxError:語法錯誤
const c = """"; //SyntaxError: Unexpected string
</script>
錯誤的處理
- 錯誤處理的方式有兩種:捕獲錯誤和拋出錯誤;
- 捕獲錯誤:
try ... catch;
<script>
try {
let b;
console.log(b.xxx);
} catch (error) {
console.log(error.message);
console.log(error.stack);
}
console.log('出錯之后');
</script>
- 拋出錯誤:
throw error,錯誤由調(diào)用者進行處理;
<script>
function something() {
if (Date.now % 2 === 1) {
console.log('當(dāng)前時間為奇數(shù),可以執(zhí)行任務(wù)');
} else {
throw new Error('當(dāng)前時間為偶數(shù),拋出異常 無法執(zhí)行任務(wù)');
}
}
//拋出錯誤之后 調(diào)用者來處理了
try {
something();
} catch (error) {
alert(error.message);
}
</script>
Promise
- Promise是JS中進行異步編程的一種解決方案;
- 從語法上來說,Promise是一個構(gòu)造函數(shù);
- 從功能上來說,Promise對象用來封裝一個異步操作并可以獲取其結(jié)果;
Promise的狀態(tài)
- 初始化狀態(tài)為pending;
- pending變?yōu)閞esolved;
- pending變?yōu)閞eiected;
- 一個Promise對象,其狀態(tài)只能改變一次,無論變?yōu)槌晒€是失敗,都會有一個結(jié)果數(shù)據(jù),成功的結(jié)果數(shù)據(jù)一般稱為value,失敗的結(jié)果數(shù)據(jù)一般稱為reason;
- Promise執(zhí)行的基本流程如下:

image.png
Promise的基本使用
- 首先創(chuàng)建Promise實例對象;
- 在執(zhí)行器中執(zhí)行異步任務(wù);
- 獲取異步任務(wù)的處理結(jié)果;
<script>
//1.創(chuàng)建Promise實例對象
const promise = new Promise((resolve, reject) => {
//2.在執(zhí)行器中 執(zhí)行異步任務(wù)
setTimeout(() => {
const time = Date.now();
if (time % 2 === 0) {
resolve('成功的數(shù)據(jù),time = ' + time);
} else {
reject('失敗的數(shù)據(jù),time = ' + time);
}
})
}, 1000);
//3.處理異步任務(wù)的結(jié)果
promise.then(
value => {
console.log('成功的回調(diào)', value);
},
reason => {
console.log('失敗的回調(diào)', reason);
}
)
</script>
Promise的優(yōu)點
- 首先Promise指定回調(diào)函數(shù)的方式更加靈活;
- 純回調(diào)函數(shù)形式,指定回調(diào)函數(shù)必須在異步任務(wù)執(zhí)行之前;
- Promise形式,指定回調(diào)函數(shù)在執(zhí)行異步任務(wù)前后均可以,更加靈活;
- 其次Promise支持鏈?zhǔn)秸{(diào)用,可以解決回調(diào)地獄問題,終極解決方案為:async/await;
<script>
//1.使用純回調(diào)函數(shù)的形式
function successCallback(result) {
console.log('成功結(jié)果:' + result);
}
function failCallback(error) {
console.log('失敗原因:' + error);
}
//必須在異步任務(wù)執(zhí)行之前 指定回調(diào)函數(shù)
createAudioFileAsync(audioSettings, successCallback, failCallback);
//2.使用Promise的形式
const promise = createAudioFileAsync(audioSettings);
//指定回調(diào)函數(shù) 非常靈活 可以在異步任務(wù)執(zhí)行前后 指定均可以
promise.then(successCallback, failCallback);
</script>
<script>
function failCallback(error) {
console.log('失敗原因:' + error);
}
//案例:三個請求 依次依賴
//1.回調(diào)嵌套地獄 下一層函數(shù)的調(diào)用 依賴上一層函數(shù)的結(jié)果
doFirstThing(function (result) {
doSecondThing(result, function (newResult) {
doThirdThing(newResult, function (lastResult) {
console.log('lastResult =', lastResult);
}, failCallback);
}, failCallback);
}, failCallback);
//2.使用Promise鏈?zhǔn)秸{(diào)用 解決回調(diào)地獄問題
doFirstThing()
.then(function (result) {
return doSecondThing(result);
})
.then(function (newResult) {
return doThirdThing(newResult);
})
.then(function (lastResult) {
console.log('lastResult =', lastResult);
})
.catch(failCallback);
//3.回調(diào)地獄的終極解決方案: async/await
async function request() {
try {
const result = await doFirstThing();
const newResult = await doSecondThing(result);
const lastResult = await doThirdThing(newResult);
console.log('lastResult =', lastResult);
} catch (error) {
failCallback(error);
}
}
</script>
Promise常見API

image.png
<script>
//then value --> 異步執(zhí)行成功
//catch reason --> 異步執(zhí)行失敗
new Promise((resolve, reject) => {
setTimeout(() => {
resolve('111111');
}, 5000);
}).then((value) => {
console.log(value);
}).catch((reason) => {
console.log(reason);
});
//Promise.resolve() 或者 Promise.reject() 均會返回一個Promise實例對象
const p1 = new Promise((resolve, reject) => {
resolve(1);
});
const p2 = Promise.resolve(2);
const p3 = Promise.reject(3);
p1.then(value => console.log(value));
p2.then(value => console.log(value));
p3.catch(reason => console.log(reason));
//pAll 數(shù)組中異步操作只要有一個失敗 就直接失敗
const pAll = Promise.all([p1, p2, p3]);
pAll.then(
value => {
console.log('all onResolve()', value);
},
reason => {
console.log('all onReject()', reason);
}
)
//異步操作數(shù)組中的 某個異步操作最先返回結(jié)果 就是pRace的最終結(jié)果
const pRace = Promise.race([p1, p2, p3]);
pRace.then(
value => {
console.log('all onResolve()', value);
},
reason => {
console.log('all onReject()', reason);
}
)
</script>
-
Promise.resolve(value):返回值為一個新的promise,參數(shù)value值可以是promise,可以是非promise- 當(dāng)value為非promise時,那么新promise的狀態(tài)結(jié)果為resolve成功;
- 當(dāng)value為promise時,那么新promise的狀態(tài)結(jié)果為value的狀態(tài)結(jié)果;
-
Promise.reject(value):返回值為一個新的promise,其狀態(tài)結(jié)果為reject失??; -
Promise.all(promise數(shù)組):返回值為一個新的promise,其狀態(tài)結(jié)果為:- 當(dāng)promise數(shù)組中存在一個狀態(tài)失敗的,那么新promise的狀態(tài)結(jié)果為失??;
- 當(dāng)promise數(shù)組中都成功,那么新promise的狀態(tài)結(jié)果為一個數(shù)組集合值;
-
Promise.race(promise數(shù)組):返回值為一個新的promise,其狀態(tài)結(jié)果為:promise數(shù)組中先返回狀態(tài)結(jié)果的promise的狀態(tài)結(jié)果;
Promise的使用注意事項
- promise的狀態(tài)改變分為三種情況:
- 執(zhí)行成功resolve(value),pending --> resolve;
- 執(zhí)行失敗reject(reason),pending --> reject;
- 拋出異常 throw error,pending --> reject;
- 一個promise對象,可以指定多個狀態(tài)回調(diào),且多個狀態(tài)回調(diào)都會執(zhí)行;
<script>
const p = new Promise((resolve, reject) => {
// resolve(1); //成功 pending --> resolve
// reject(2); //失敗 pending --> reject
throw new Error('報錯了'); //拋出異常 pending --> reject
});
//promise指定多個回調(diào) 都會調(diào)用
p.then(
value => { },
reason => { console.log('reason', reason) }
);
p.then(
value => { },
reason => { console.log('reason', reason) }
);
</script>
- 如何控制
改變promise狀態(tài)和指定回調(diào)函數(shù)的先后順序?- 常規(guī)情況下:先指定回調(diào)函數(shù),再改變promise狀態(tài),執(zhí)行回調(diào)函數(shù);
<script>
//先指定回調(diào)函數(shù) 再改變狀態(tài)
new Promise((resolve, reject) => {
//2.異步執(zhí)行 再改變狀態(tài)(同時指定數(shù)據(jù)) 異步執(zhí)行下面指定的回調(diào)函數(shù)
setTimeout(() => {
resolve(1);
})
}).then(
//1.先指定回調(diào)函數(shù),promise會保存當(dāng)前指定的回調(diào)函數(shù)
value => { console.log('value', value) },
reason => { console.log('reason', reason) }
);
//先指定回調(diào)函數(shù) 再改變狀態(tài)
new Promise((resolve, reject) => {
//1.先改變狀態(tài)(同時指定數(shù)據(jù))
resolve(1);
}).then(
//2.后指定回調(diào)函數(shù) 異步執(zhí)行回調(diào)函數(shù)
value => { console.log('value', value) },
reason => { console.log('reason', reason) }
);
//先指定回調(diào)函數(shù) 再改變狀態(tài)
const p = new Promise((resolve, reject) => {
//2.異步執(zhí)行 再改變狀態(tài)(同時指定數(shù)據(jù)) 異步執(zhí)行下面指定的回調(diào)函數(shù)
setTimeout(() => {
resolve(1);
})
});
setTimeout(() => {
p.then(
//1.先指定回調(diào)函數(shù),promise會保存當(dāng)前指定的回調(diào)函數(shù)
value => { console.log('value', value) },
reason => { console.log('reason', reason) }
);
}, 2000);
</script>
- promise.then()會返回一個新的promise對象,此promise的狀態(tài)結(jié)果由什么決定?
- 由then()指定的回調(diào)函數(shù)執(zhí)行的結(jié)果決定;
- then()指定的回調(diào)函數(shù),沒有返回值,則新的promise對象狀態(tài)變成resolve,value值為undefined;
- then()指定的回調(diào)函數(shù),返回非promise的任意值value,則新的promise對象狀態(tài)變成resolve,會執(zhí)行成功的回調(diào),且獲取value值;
- then()指定的回調(diào)函數(shù),拋出異常,則新的promise對象狀態(tài)變成reject,會執(zhí)行失敗的回調(diào);
- then()指定的回調(diào)函數(shù),返回另一個新的promise,則此promise的狀態(tài)結(jié)果會成為新promise的狀態(tài)結(jié)果;
<script>
new Promise((resolve, reject) => {
resolve(1);
}).then(
value => { console.log('onResolved1', value) },
reason => {
console.log('onRejected1', reason)
// return 2;
// return Promise.resolve(3);
// return Promise.reject(4);
// throw 5;
}
).then(
value => { console.log('onResolved2', value) },
reason => { console.log('onRejected2', reason) }
);
</script>
- promise如何串聯(lián)多個操作任務(wù)?
- promise.then()可返回一個新的promise;
- promise.then()的鏈?zhǔn)秸{(diào)用可串聯(lián)多個同步/異步任務(wù);
<script>
new Promise((resolve, reject) => {
setTimeout(() => {
console.log('執(zhí)行異步任務(wù)1');
resolve(1);
}, 1000);
}).then(
value => {
console.log('異步任務(wù)1的結(jié)果:', value);
console.log('執(zhí)行同步任務(wù)2');
return 2;
},
reason => {
console.log('onRejected1', reason);
}
).then(
value => {
console.log('同步任務(wù)2的結(jié)果:', value);
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('執(zhí)行異步任務(wù)3');
resolve(3);
}, 1000);
})
},
reason => {
console.log('onRejected2', reason);
}
).then(
value => {
console.log('異步任務(wù)3的結(jié)果:', value);
}
);
</script>

image.png
- promise的異常傳透:
- 當(dāng)使用promise的then鏈?zhǔn)秸{(diào)用時,可以再最后指定失敗的回調(diào);
- 前面任何操作出現(xiàn)了異常,都會傳到最后失敗的回調(diào);
<script>
new Promise((resolve, reject) => {
reject(1);
}).then(
value => {
console.log('onResolve1:', value);
return 2;
},
// reason => {
// throw reason;
// }
).then(
value => {
console.log('onResolve2:', value);
return 3;
},
// reason => {
// throw reason;
// }
).then(
value => {
console.log('onResolve3:', value);
},
// reason => {
// throw reason;
// }
).catch(
reason => {
console.log('onReject: ', reason);
}
)
</script>
- . catch失敗處理,上面沒有失敗的處理,就會執(zhí)行. catch中的代碼,
沒有失敗的處理等價于reason => { throw reason },拋出了異常,然后一直往下傳遞異常,最終會執(zhí)行. catch中的代碼; - 如何中斷promise鏈?
- 當(dāng)使用promise的then鏈?zhǔn)秸{(diào)用時,在中間中斷,不再調(diào)用后面的回調(diào)函數(shù);
- 方案:在回調(diào)函數(shù)中返回一個pending狀態(tài)的promise對象;
<script>
new Promise((resolve, reject) => {
reject(1);
}).then(
value => {
console.log('onResolve1:', value);
return 2;
},
).then(
value => {
console.log('onResolve2:', value);
return 3;
},
).then(
value => {
console.log('onResolve3:', value);
},
).catch(
reason => {
console.log('onReject1: ', reason);
// throw reason;
// return Promise.reject(3);
//返回一個pending狀態(tài)的promise
//下面的回調(diào)函數(shù)不會執(zhí)行
return new Promise(() => { });
}
).then(
value => {
console.log('onResolve3:', value);
},
reason => {
console.log('onReject2: ', reason);
}
)
</script>
- 注意.catch()函數(shù)也會返回一個新的promise對象;
自定義Promise
- 函數(shù)對象,代碼如下:
//自定義Promise函數(shù)模塊
(function (window) {
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
//Promise的構(gòu)造函數(shù)
function Promise(excutor) {
const self = this;
//promise狀態(tài) 初始化為pending
self.status = PENDING;
//promise異步操作的結(jié)果數(shù)據(jù)
self.data = undefined;
//promise的回調(diào)函數(shù)
self.callbacks = [];
function resolve(value) {
if (self.status !== PENDING) {
return;
}
//將狀態(tài)改成resolved
self.status = RESOLVED;
self.data = value;
//若存在callback回調(diào)函數(shù),則立即異步執(zhí)行回調(diào)函數(shù)
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(element => {
element.onResolved(value);
});
});
}
}
function reject(reason) {
if (self.status !== PENDING) {
return;
}
self.status = REJECTED;
self.data = reason;
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(element => {
element.onRejected(reason);
});
});
}
}
try {
excutor(resolve, reject);
} catch (error) {
//捕獲異常了 執(zhí)行reject方法 狀態(tài)成為rejected
reject(error);
}
}
//Promise原型上的函數(shù)方法
Promise.prototype.then = function (onResolved, onRejected) {
//當(dāng)前promise對象
const self = this;
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
//返回一個新的promise對象
return new Promise((resolve, reject) => {
//處理函數(shù)
function handle(callback) {
//新promise對象的狀態(tài)結(jié)果 由當(dāng)前promise對象的狀態(tài)結(jié)果決定
//1.當(dāng)前promise結(jié)果為拋出異常,則新的promise結(jié)果為失敗,值為異常error
//2.當(dāng)前promise結(jié)果為非promise,則新的promise結(jié)果為成功,值為異常value
//3.當(dāng)前promise結(jié)果為promise,則新的promise結(jié)果為promise的結(jié)果
try {
const result = callback(self.data);
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
if (this.status === RESOLVED) {
//立即異步執(zhí)行 當(dāng)前promise對象 成功的回調(diào)函數(shù)
setTimeout(() => {
handle(onResolved);
});
} else if (self.status === REJECTED) {
setTimeout(() => {
handle(onRejected);
});
} else {
//將成功和失敗的回調(diào)函數(shù)保存到callbacks容器中
self.callbacks.push({
onResolved(value) {
handle(onResolved);
},
onRejected(reason) {
handle(onRejected);
}
});
}
});
if (self.status === PENDING) {
//保存回調(diào)方法 到一個對象中
self.callbacks.push({
onResolved,
onRejected
})
} else if (self.status === RESOLVED) {
setTimeout(() => {
resolve(self.data)
});
} else {
setTimeout(() => {
reject(self.data);
});
}
}
Promise.prototype.catch = function (onRejected) {
Promise.prototype.then(undefined, onRejected);
}
//Promise函數(shù)對象方法
Promise.resolve = function (value) {
//返回一個狀態(tài)結(jié)果為 成功或失敗的promise對象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject);
} else {
resolve(value);
}
})
}
Promise.reject = function (reason) {
//返回一個狀態(tài)結(jié)果為失敗的promise對象
return new Promise((resolve, reject) => {
reject(reason);
})
}
Promise.all = function (promises) {
//保存所有成功的value的數(shù)組
const values = new Array(promises.length);
//記錄成功promise的數(shù)量
let resloveCount = 0;
return new Promise((reslove, reject) => {
promises.forEach((p, index) => {
p.then(
value => {
resloveCount++;
values[index] = value;
if (resloveCount === promises.length) {
reslove(values);
}
},
reason => {
reject(reason);
}
)
});
});
}
Promise.race = function (promises) {
return new Promise((resove, reject) => {
promises.forEach((p, index) => {
p.then(
value => {
resove(value);
},
reason => {
reject(reason);
}
)
});
});
}
//向外暴露Promise的構(gòu)造函數(shù)
window.Promise = Promise;
})(window)
- 類Class對象,代碼如下:
//自定義Promise函數(shù)模塊
(function (window) {
const PENDING = 'pending';
const RESOLVED = 'resolved';
const REJECTED = 'rejected';
class Promise {
constructor(excutor) {
//Promise的構(gòu)造函數(shù)
const self = this;
//promise狀態(tài) 初始化為pending
self.status = PENDING;
//promise異步操作的結(jié)果數(shù)據(jù)
self.data = undefined;
//promise的回調(diào)函數(shù)
self.callbacks = [];
function resolve(value) {
if (self.status !== PENDING) {
return;
}
//將狀態(tài)改成resolved
self.status = RESOLVED;
self.data = value;
//若存在callback回調(diào)函數(shù),則立即異步執(zhí)行回調(diào)函數(shù)
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(element => {
element.onResolved(value);
});
});
}
}
function reject(reason) {
if (self.status !== PENDING) {
return;
}
self.status = REJECTED;
self.data = reason;
if (self.callbacks.length > 0) {
setTimeout(() => {
self.callbacks.forEach(element => {
element.onRejected(reason);
});
});
}
}
try {
excutor(resolve, reject);
} catch (error) {
//捕獲異常了 執(zhí)行reject方法 狀態(tài)成為rejected
reject(error);
}
}
//Promise原型上的函數(shù)方法
then(onResolved, onRejected) {
//當(dāng)前promise對象
const self = this;
onResolved = typeof onResolved === 'function' ? onResolved : value => value;
onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
//返回一個新的promise對象
return new Promise((resolve, reject) => {
//處理函數(shù)
function handle(callback) {
//新promise對象的狀態(tài)結(jié)果 由當(dāng)前promise對象的狀態(tài)結(jié)果決定
//1.當(dāng)前promise結(jié)果為拋出異常,則新的promise結(jié)果為失敗,值為異常error
//2.當(dāng)前promise結(jié)果為非promise,則新的promise結(jié)果為成功,值為異常value
//3.當(dāng)前promise結(jié)果為promise,則新的promise結(jié)果為promise的結(jié)果
try {
const result = callback(self.data);
if (result instanceof Promise) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
}
if (this.status === RESOLVED) {
//立即異步執(zhí)行 當(dāng)前promise對象 成功的回調(diào)函數(shù)
setTimeout(() => {
handle(onResolved);
});
} else if (self.status === REJECTED) {
setTimeout(() => {
handle(onRejected);
});
} else {
//將成功和失敗的回調(diào)函數(shù)保存到callbacks容器中
self.callbacks.push({
onResolved(value) {
handle(onResolved);
},
onRejected(reason) {
handle(onRejected);
}
});
}
});
if (self.status === PENDING) {
//保存回調(diào)方法 到一個對象中
self.callbacks.push({
onResolved,
onRejected
})
} else if (self.status === RESOLVED) {
setTimeout(() => {
resolve(self.data)
});
} else {
setTimeout(() => {
reject(self.data);
});
}
}
catch(onRejected) {
Promise.prototype.then(undefined, onRejected);
}
//Promise函數(shù)對象方法
static resolve(value) {
//返回一個狀態(tài)結(jié)果為 成功或失敗的promise對象
return new Promise((resolve, reject) => {
if (value instanceof Promise) {
value.then(resolve, reject);
} else {
resolve(value);
}
})
}
static reject(reason) {
//返回一個狀態(tài)結(jié)果為失敗的promise對象
return new Promise((resolve, reject) => {
reject(reason);
})
}
static all(promises) {
//保存所有成功的value的數(shù)組
const values = new Array(promises.length);
//記錄成功promise的數(shù)量
let resloveCount = 0;
return new Promise((reslove, reject) => {
promises.forEach((p, index) => {
p.then(
value => {
resloveCount++;
values[index] = value;
if (resloveCount === promises.length) {
reslove(values);
}
},
reason => {
reject(reason);
}
)
});
});
}
static race(promises) {
return new Promise((resove, reject) => {
promises.forEach((p, index) => {
p.then(
value => {
resove(value);
},
reason => {
reject(reason);
}
)
});
});
}
}
//向外暴露Promise的構(gòu)造函數(shù)
window.Promise = Promise;
}
)(window)
async與await
-
async 函數(shù):函數(shù)的返回值是promise對象,promise對象的狀態(tài)結(jié)果由async函數(shù)執(zhí)行的返回值決定;
<script>
async function test() {
// return 1;
throw 2;
// return Promise.resolve(3);
}
//返回結(jié)果為promise對象
const result = test();
result.then(
value => {
console.log('onResolved()',value);
},
reason => {
console.log('onRejected()',reason);
}
);
</script>
-
await 表達式:一般情況下await右側(cè)的表達式為promise對象,也可以是其他的值;‘- 若表達式是promise對象,await返回的是promise成功的值;
- 若表達式是其他值,直接將此值作為await的返回值;
- 注意事項:
- await必須寫在async函數(shù)中,但async函數(shù)中可以沒有await;
- 如果await的promise失敗了,就會拋出異常,需要通過try...catch來捕獲處理;
<script>
function test2() {
return new Promise((reslove, reject) => {
setTimeout(() => {
// reslove(5);
reject(6);
}, 1000);
})
}
async function test3() {
try {
//表達式是promise對象,await返回的是promise成功的值
const value = await test2();
console.log(value);
} catch (error) {
//await的promise失敗了,就會拋出異常,需要通過try...catch來捕獲處理
console.log('得到失敗的結(jié)果', error);
}
//表達式是其他值,直接將此值作為await的返回值
const value = test4();
console.log(value);
}
function test4() {
return 6;
}
test3();
</script>
異步執(zhí)行的宏隊列與微隊列
- 在JS中 存儲 待執(zhí)行回調(diào)函數(shù)的 隊列 有兩種特定的隊列,分別為宏隊列和微隊列;
- 宏隊列:用來保存待執(zhí)行的宏任務(wù)回調(diào)函數(shù),例如定時器回調(diào),DOM事件回調(diào),ajax回調(diào);
- 微隊列:用來保存待執(zhí)行的微任務(wù)回調(diào)函數(shù),例如Promise回調(diào),MutationObserver回調(diào);
- JS執(zhí)行時會區(qū)分 這兩個隊列;
- JS引擎首先必須先執(zhí)行完所有的初始化同步任務(wù)代碼;
-
每次準(zhǔn)備取出第一個宏任務(wù)執(zhí)行前,都要將所有微任務(wù)一個一個取出來執(zhí)行;
<script>
setTimeout(() => {
//回調(diào)函數(shù) 放入宏隊列
console.log('timeout callback1()');
Promise.resolve(3).then(
value => {
//回調(diào)函數(shù) 放入微隊列
console.log('Promise onResolved3()', value);
}
)
}, 0);
setTimeout(() => {
//回調(diào)函數(shù) 放入宏隊列
console.log('timeout callback2()');
}, 0);
Promise.resolve(1).then(
value => {
//回調(diào)函數(shù) 放入微隊列
console.log('Promise onResolved1()', value);
}
)
Promise.resolve(2).then(
value => {
//回調(diào)函數(shù) 放入微隊列
console.log('Promise onResolved2()', value);
}
)
</script>

image.png