Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

解惑Promise与异步函数(async & await)的执行顺序 #147

Open
JasonWu73 opened this issue Aug 12, 2020 · 0 comments
Open

解惑Promise与异步函数(async & await)的执行顺序 #147

JasonWu73 opened this issue Aug 12, 2020 · 0 comments
Labels
知识点 单知识点

Comments

@JasonWu73
Copy link
Owner

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关联方法位于异步回调内:

  1. 按顺序执行完Promise中的同步方法
  2. 按顺序执行完Promise外的同步方法
  3. 当Promise内的异步方法执行完毕后,触发其回调函数
  4. 按顺序执行完回调函数中非Promise关联方法的同步方法
  5. 按顺序执行回调函数中Promise关联方法(resolvereject,哪个在前就执行哪个)
    - 若方法为resolve(error),则自动抛出错误error
    - 若方法为resolve(value),则只有通过then才能得到value

Promise关联方法位于异步回调外:

  1. 按顺序执行完Promise中的同步方法
  2. 按顺序执行完Promise外的同步方法
  3. 执行Promise关联方法
  • 若方法为resolve(error),则自动报出错误error
  • 若方法为resolve(value),则只通过then才能得到value
  1. 执行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关联方法位于异步回调内:

  1. 遇到await关键字时,按顺序执行完其表达式Promise中的同步方法
  2. 等待Promise中的异步方法执行完毕
  3. 按顺序执行完异步回调中非Promise关联方法的同步方法
  4. 执行异步回调中Promise关联方法
  • 当关联方法为reject(error)时,则直接抛出错误error
  1. 执行await表达式的下一条语句
  • 若使用了await表达式的结果,执行resolve(value)方法得到结果值value
  • 若没有使用await表达式的结果,执行该条语句,直到遇到使用该await表达式的结果值时,才调用resolve方法

Promise关联方法位于异步回调外:

  1. 遇到await关键字时,按顺序执行完其表达式Promise中的非Promise关联方法的同步方法
  2. 关联方法是否为reject(error)
  • 是,则直接抛出错误error
  1. 执行await表达式的下一条语句
  • 若使用了await表达式的结果,执行resolve(value)方法得到结果值value
  • 若没有使用await表达式的结果,执行该条语句,直到遇到使用该await表达式的结果值时,才调用resolve方法
  1. 执行Promise中的异步方法

Promise与Async函数的共同点

因为async/await只作为用来简化使用基本Promise API的语法,所以Promise的特性,在异步函数中同样有效。

  • Promise关联方法总是在其Promise范围内的其他同步方法之后才被执行
  • 哪怕没有显示地捕获错误,reject也会自动抛出错误
  • resolve在没有显示调用时,其回调值会被忽略
  • promise对象本身也是一个异步方法
@JasonWu73 JasonWu73 added the 知识点 单知识点 label Aug 12, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
知识点 单知识点
Projects
None yet
Development

No branches or pull requests

1 participant