前言

对于回调来讲,Promise 的到来看似只解决了回调场景中的状态处理问题,但是JavaScript中令人头疼不是回调,而是 回调嵌套。同时,Promise的出现,也不能彻底解决回调嵌套的带来的代码维护和可读性的问题。

  • 原生回调嵌套

    1. function increase(num, callback) {
    2. setTimeout(() => {
    3. if( !(num >= 0) ) {
    4. callback(new Error('The parameters must be greater than zero'), null)
    5. } else {
    6. let result = num + 1;
    7. callback(null, result);
    8. }
    9. }, 100)
    10. }
    11. increase(1, (err, result1) => {
    12. if(!err) {
    13. console.log(`result1 = ${result1}`)
    14. increase(result1, (err, result2) => {
    15. if(!err) {
    16. console.log(`result2 = ${result2}`)
    17. increase(result2, (err, result3) => {
    18. if(!err) {
    19. console.log(`result3 = ${result3}`)
    20. } else {
    21. console.log(err)
    22. }
    23. })
    24. } else {
    25. console.log(err)
    26. }
    27. })
    28. } else {
    29. console.log(err)
    30. }
    31. })
    32. // 运行结果
    33. // "result1 = 2"
    34. // "result1 = 3"
    35. // "result1 = 4"
  • Promise 处理回调嵌套

    1. function increase(num) {
    2. return new Promise((resolve, reject) => {
    3. setTimeout(() => {
    4. if( !(num >= 0) ) {
    5. reject(new Error('The parameters must be greater than zero'))
    6. } else {
    7. let result = num + 1;
    8. resolve(result);
    9. }
    10. }, 100)
    11. })
    12. }
    13. increase(1).then((result1) => {
    14. console.log(`result1 = ${result1}`)
    15. increase(result1).then((result2) => {
    16. console.log(`result2 = ${result2}`)
    17. increase(result2).then((result3) => {
    18. console.log(`result3 = ${result3}`)
    19. }).catch(err => console.log(err));
    20. }).catch(err => console.log(err));
    21. }).catch(err => console.log(err));
    22. // 运行结果
    23. // "result1 = 2"
    24. // "result1 = 3"
    25. // "result1 = 4"

    所以这时候,需要一个更优雅处理Promise 嵌套任务 的语法,因此,async/await 就横空出世,也就是直接或间接解决了 回调嵌套 的问题。
    一句话,async/await 的出现是为了解决回调嵌套的操作繁琐和可读性差的问题。

    aysnc/await的使用

  • async 是 声明 在回调环境函数

  • await 是 运行 在等待回调结果过程中
  • Promise 是封装了回调操作的 原子任务

举一个简单的例子

  1. // 封装原子任务
  2. function increase(num) {
  3. return new Promise((resolve, reject) => {
  4. setTimeout(() => {
  5. if( !(num >= 0) ) {
  6. reject(new Error('The parameters must be greater than zero'))
  7. } else {
  8. resolve(num + 1)
  9. }
  10. }, 100);
  11. }).catch(err => console.log(err))
  12. }
  13. // 声明任务环境
  14. async function envIncrease() {
  15. let num = 1;
  16. // 等待回调任务结果1返回
  17. let result1 = await increase(num);
  18. console.log(`result1 = ${result1}`);
  19. // 等待回调任务结果2返回
  20. let result2 = await increase(result1);
  21. console.log(`result2 = ${result2}`);
  22. // 等待回调任务结果3返回
  23. let result3 = await increase(result2);
  24. console.log(`result3 = ${result3}`);
  25. return result3
  26. }
  27. // 声明任务环境
  28. async function env() {
  29. // 等待 环境 Increase 的结果返回
  30. let result = await envIncrease()
  31. console.log(`result = ${result}`);
  32. }
  33. // 运行环境
  34. env()
  35. // 运行结果
  36. // "result1 = 2"
  37. // "result1 = 3"
  38. // "result1 = 4"