Promise 的基本流程
// 1. 创建一个新的promise对象
const p = new Promise((resolve, reject) => {// 执行器函数 同步回调
console.log('执行 excutor')
// 2. 执行异步操作任务
setTimeout(() => {
const time = Date.now() // 如果当前时间是偶数就代表成功, 否则代表失败
// 3.1. 如果成功了, 调用resolve(value)
if (time %2 == 0) {
resolve('成功的数据, time=' + time)
} else {
// 3.2. 如果失败了, 调用reject(reason)
reject('失败的数据, time=' + time)
}
}, 1000);
})
console.log('new Promise()之后')
// setTimeout(() => {
p.then(
value => { // 接收得到成功的value数据 onResolved
console.log('成功的回调', value)
},
reason => {// 接收得到失败的reason数据 onRejected
console.log('失败的回调', reason)
}
)
// }, 2000);
为什么要用Promise
1. 指定回调函数的方式更加灵活:
旧的: 必须在启动异步任务前指定
promise: 启动异步任务 => 返回promie对象 => 给promise对象绑定回调函数(甚至可以在异步任务结束后指定)
2. 支持链式调用, 可以解决回调地狱问题
什么是回调地狱?
回调函数嵌套调用, 外部回调函数异步执行的结果是嵌套的回调函数执行的条件
回调地狱的缺点?
不便于阅读 / 不便于异常处理
解决方案?
promise链式调用
终极解决方案?
async/await
// 成功的回调函数
function successCallback(result) {
console.log("声音文件创建成功: " + result);
}
// 失败的回调函数
function failureCallback(error) {
console.log("声音文件创建失败: " + error);
}
/* 1.1 使用纯回调函数 */
createAudioFileAsync(audioSettings, successCallback, failureCallback)
/* 1.2. 使用Promise */
const promise = createAudioFileAsync(audioSettings); // 2
setTimeout(() => {
promise.then(successCallback, failureCallback);
}, 3000);
回调地狱
doSomething(function(result) {
doSomethingElse(result, function(newResult) {
doThirdThing(newResult, function(finalResult) {
console.log('Got the final result: ' + finalResult)
}, failureCallback)
}, failureCallback)
}, failureCallback)
使用promise的链式调用解决回调地狱
doSomething()
.then(function(result) {
return doSomethingElse(result)
})
.then(function(newResult) {
return doThirdThing(newResult)
})
.then(function(finalResult) {
console.log('Got the final result: ' + finalResult)
})
.catch(failureCallback)
async/await: 回调地狱的终极解决方案
async function request() {
try {
const result = await doSomething()
const newResult = await doSomethingElse(result)
const finalResult = await doThirdThing(newResult)
console.log('Got the final result: ' + finalResult)
} catch (error) {
failureCallback(error)
}
}