解惑Promise与异步函数(async & await)的执行顺序
JasonWu73 opened this issue · 0 comments
JasonWu73 commented
Promise
常规
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
resolve('6-success')
reject('6-error')
console.log('5')
}, 10)
console.log('2')
})
const executeByPromise = () => {
asyncMethod()
.then((data) => console.log(data))
.catch(error => console.log(error))
console.log('3')
console.log('4')
}
executeByPromise()
// 1 2 3 4 5 6-success
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
resolve('6-success')
reject('6-error')
console.log('5')
}, 10)
console.log('2')
})
const executeByPromise = () => {
asyncMethod()
console.log('3')
console.log('4')
}
executeByPromise()
// 1 2 3 4 5
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
reject('6-error')
resolve('6-success')
console.log('5')
}, 10)
console.log('2')
})
const executeByPromise = () => {
asyncMethod()
.then((data) => console.log(data))
.catch(error => console.log(error))
console.log('3')
console.log('4')
}
executeByPromise()
// 1 2 3 4 5 6-error
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
reject('6-error')
resolve('6-success')
console.log('5')
}, 10)
console.log('2')
})
const executeByPromise = () => {
asyncMethod()
console.log('3')
console.log('4')
}
executeByPromise()
// 1 2 3 4 5 Uncaught (in promise) 6-error
非常规
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
console.log('6')
}, 10)
// 错误写法:将回调写在了异步方法之外
reject('5-error')
console.log('2')
})
const executeByPromise = () => {
asyncMethod()
console.log('3')
console.log('4')
}
executeByPromise()
// 1 2 3 4 Uncaught (in promise) 5-error 6
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
console.log('6')
}, 10)
// 错误写法:将回调写在了异步方法之外
resolve('5-success')
console.log('2')
})
const executeByPromise = () => {
asyncMethod()
console.log('3')
console.log('4')
}
executeByPromise()
// 1 2 3 4 6
总结
Promise关联方法:
resolve(value)
和reject(error)
。
Promise关联方法位于异步回调内:
- 按顺序执行完Promise中的同步方法
- 按顺序执行完Promise外的同步方法
- 当Promise内的异步方法执行完毕后,触发其回调函数
- 按顺序执行完回调函数中非Promise关联方法的同步方法
- 按顺序执行回调函数中Promise关联方法(
resolve
与reject
,哪个在前就执行哪个)
- 若方法为resolve(error)
,则自动抛出错误error
- 若方法为resolve(value)
,则只有通过then
才能得到value
Promise关联方法位于异步回调外:
- 按顺序执行完Promise中的同步方法
- 按顺序执行完Promise外的同步方法
- 执行Promise关联方法
- 若方法为
resolve(error)
,则自动报出错误error
- 若方法为
resolve(value)
,则只通过then
才能得到value
- 执行Promise内的异步方法
异步函数(async & await)
常规
const asyncMethod = () => new Promise(resolve => {
console.log('1')
// 执行异步方法
setTimeout(() => {
resolve('6-success')
console.log('3')
}, 10)
console.log('2')
})
const executeByKeyword = async () => {
const result = await asyncMethod()
console.log('4')
console.log('5')
console.log(result)
}
executeByKeyword()
// 1 2 3 4 5 6-success
const asyncMethod = () => new Promise(resolve => {
console.log('1')
// 执行异步方法
setTimeout(() => {
resolve('4-success')
console.log('3')
}, 10)
console.log('2')
})
const executeByKeyword = async () => {
const result = await asyncMethod()
console.log(result)
console.log('5')
console.log('6')
}
executeByKeyword()
// 1 2 3 4-success 5 6
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
reject('4-error')
console.log('3')
}, 10)
console.log('2')
})
const executeByKeyword = async () => {
const result = await asyncMethod()
console.log('5')
console.log('6')
console.log(result)
}
executeByKeyword()
// 1 2 3 Uncaught (in promise) 4-error
非常规
const asyncMethod = () => new Promise(resolve => {
console.log('1')
// 执行异步方法
setTimeout(() => {
console.log('6')
}, 10)
// 错误写法:将回调写在了异步方法之外
resolve('3-success')
console.log('2')
})
const executeByKeyword = async () => {
const result = await asyncMethod()
console.log(result)
console.log('4')
console.log('5')
}
executeByKeyword()
// 1 2 3-success 4 5 6
const asyncMethod = () => new Promise(resolve => {
console.log('1')
// 执行异步方法
setTimeout(() => {
console.log('6')
}, 10)
// 错误写法:将回调写在了异步方法之外
resolve('5-success')
console.log('2')
})
const executeByKeyword = async () => {
const result = await asyncMethod()
console.log('3')
console.log('4')
console.log(result)
}
executeByKeyword()
// 1 2 3 4 5-success 6
const asyncMethod = () => new Promise((resolve, reject) => {
console.log('1')
// 执行异步方法
setTimeout(() => {
console.log('6')
}, 10)
// 错误写法:将回调写在了异步方法之外
reject('3-error')
console.log('2')
})
const executeByKeyword = async () => {
const result = await asyncMethod()
console.log('4')
console.log('5')
console.log(result)
}
executeByKeyword()
// 1 2 Uncaught (in promise) 3-error 6
Promise关联方法位于异步回调内:
- 遇到
await
关键字时,按顺序执行完其表达式Promise中的同步方法 - 等待Promise中的异步方法执行完毕
- 按顺序执行完异步回调中非Promise关联方法的同步方法
- 执行异步回调中Promise关联方法
- 当关联方法为
reject(error)
时,则直接抛出错误error
- 执行
await
表达式的下一条语句
- 若使用了
await
表达式的结果,执行resolve(value)
方法得到结果值value
- 若没有使用
await
表达式的结果,执行该条语句,直到遇到使用该await
表达式的结果值时,才调用resolve
方法
Promise关联方法位于异步回调外:
- 遇到
await
关键字时,按顺序执行完其表达式Promise中的非Promise关联方法的同步方法 - 关联方法是否为
reject(error)
- 是,则直接抛出错误
error
- 执行
await
表达式的下一条语句
- 若使用了
await
表达式的结果,执行resolve(value)
方法得到结果值value
- 若没有使用
await
表达式的结果,执行该条语句,直到遇到使用该await
表达式的结果值时,才调用resolve
方法
- 执行Promise中的异步方法
Promise与Async函数的共同点
因为
async
/await
只作为用来简化使用基本Promise API的语法,所以Promise的特性,在异步函数中同样有效。
- Promise关联方法总是在其Promise范围内的其他同步方法之后才被执行
- 哪怕没有显示地捕获错误,
reject
也会自动抛出错误 resolve
在没有显示调用时,其回调值会被忽略promise
对象本身也是一个异步方法