promise多个then、catch、finally情况

14 阅读8分钟

Date: 2022-03-22

结论

先抛出结论,如下:

  1. 一个promise中,resolve、reject只会执行最先触发的那个,执行完就停止了
  2. 根据 resolve|reject 输出 then|catch、finally
  3. 多个resolve或多个reject只会执行第一个
  4. Promise立即执行函数里面的其他语句不会受到resolve、reject影响
  5. 第一次then|catch、finally执行的是promise内部的结果
  6. 第一次then|catch的参数来自promise内部的resolve、reject,finally始终无参数
  7. 第二次及以后的then一定会执行,参数来自上一个then的返回值,无返回值时参数为undefined
  8. 第二次及以后的finally一定会执行,无参数,为undefined
  9. 第二次及以后的then中如果return Error,会被下一个then作为参数输出,finally始终无参数。只会影响下一个,不会影响下下个。
  10. 第二次如果是throw Error,则会被当前紧挨着的catch语句所捕获
  11. 即:return Error只是作为一个常规的返回值(值为Error),而throw则是直接抛出异常
  12. 在then中连续写两个回调,第一个参数为then,第二个参数为catch,在then后面再写一个catch。 如果promise是resolve,在then的第一个参数中throw Error,会被下一个catch所捕获 如果promise是reject,在then的第二个参数中throw Error,会被下一个catch所捕获
  13. 即:then...catch可以将两个回调都写在then里面,直接写两个参数,then后面的catch会被当前其他语句的catch,只有前面的then内部抛出异常才会执行。

分析

case1_resovle

function testPromise1(val) {
  return new Promise((resolve, reject) => {
    resolve('成功!')
    reject('失败!')
  })
    .then((res) => {
      console.log('First then:', res)
    })
    .catch((err) => {
      console.log('First catch:', err)
    })
    .finally((res) => {
      console.log('First finally', res)
    })
}
testPromise1()

/**
 * testPromise1 执行结果:
 *
 * First then: 成功!
 * First finally: undefined
 */

case2_reject

function testPromise2(val) {
  return new Promise((resolve, reject) => {
    reject('失败!')
    resolve('成功!')
  })
    .then((res) => {
      console.log('First then:', res)
    })
    .catch((err) => {
      console.log('First catch:', err)
    })
    .finally((res) => {
      console.log('First finally:', res)
    })
}
testPromise2()

/**
 * testPromise2 执行结果:
 *
 * First catch: 失败!
 * First finally: undefined
 */

case1、case2结论:

  1. 一个promise中,resolve、reject只会执行最先触发的那个,执行完就停止了
  2. 根据 resolve|reject 先输出 promise 自己的then|catch、finall

case3_多resolve、reject

function testPromise3(val) {
  return new Promise((resolve, reject) => {
    console.log('testPromise1_1')
    resolve('成功1!')
    console.log('testPromise1_2')
    reject('失败1!')
    console.log('testPromise1_3')
    resolve('成功2!')
    console.log('testPromise1_4')
    reject('失败2!')
    console.log('testPromise1_5')
  })
    .then((res) => {
      console.log('First then:', res)
    })
    .catch((err) => {
      console.log('First catch:', err)
    })
    .finally((res) => {
      console.log('First finally:', res)
    })
}
testPromise3()

/**
 * testPromise3 执行结果:
 *
 * testPromise1_1
 * testPromise1_2
 * testPromise1_3
 * testPromise1_4
 * testPromise1_5
 * First then: 成功1!
 * First finally: undefined
 */

case3结论:

  1. 多个resolve或多个reject只会执行第一个
  2. Promise立即执行函数里面的非resolve、reject语句不会受到resolve、reject影响

case4_多then、catch、finally无return

function testPromise4(val) {
  return new Promise((resolve, reject) => {
    resolve('成功!')
    // 以下为第一次then、catch、finally
  })
    .then((res) => {
      console.log('First then:', res)
    })
    .catch((err) => {
      console.log('First catch:', err)
    })
    .finally((res) => {
      console.log('First finally:', res)
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
    })
    .catch((err) => {
      console.log('Second catch:', err)
    })
    .finally((res) => {
      console.log('Second finally:', res)
      // 以下为第三次then、catch、finally
    })
    .then((res) => {
      console.log('Third then:', res)
    })
    .catch((err) => {
      console.log('Third catch:', err)
    })
    .finally((res) => {
      console.log('Third finally:', res)
    })
}
// testPromise4()
/**
 * testPromise4 执行结果:
 *
 * First then: 成功!              --- then参数值:来自promise内部的resolve参数
 * First finally: undefined       --- finally没有参数,为undefined
 *
 * Second then: undefined         --- then参数值:来自第一个then的返回值,没有返回值为undefined
 * Second finally: undefined      --- finally没有参数,为undefined
 *
 * Third then: undefined          --- then参数值:来自第二个then的返回值,没有返回值为undefined
 * Third finally: undefined       --- finally没有参数,为undefined
 */

case5_resolve引发多then、catch、finally有return

function testPromise5(val) {
  return new Promise((resolve, reject) => {
    resolve('成功!')
    // 以下为第一次then、catch、finally
  })
    .then((res) => {
      console.log('First then:', res)
      return 'From first then'
    })
    .catch((err) => {
      console.log('First catch:', err)
      return 'From first catch'
    })
    .finally((res) => {
      console.log('First finally:', res)
      return 'From first finally'
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
      return 'From second then'
    })
    .catch((err) => {
      console.log('Second catch:', err)
      return 'From second catch'
    })
    .finally((res) => {
      console.log('Second finally:', res)
      return 'From second finally'
      // 以下为第三次then、catch、finally
    })
    .then((res) => {
      console.log('Third then:', res)
      return 'From third then'
    })
    .catch((err) => {
      console.log('Third catch:', err)
      return 'From third catch'
    })
    .finally((res) => {
      console.log('Third finally:', res)
      return 'From third finally'
    })
}
// testPromise5()
/**
 * testPromise5 执行结果:
 *
 * First then: 成功!              --- then参数值:来自promise内部的resolve参数
 * First finally: undefined       --- finally没有参数,为undefined
 *
 * Second then: From first then   --- then参数值:来自第一个then的返回值,没有返回值为undefined
 * Second finally: undefined      --- finally没有参数,为undefined
 *
 * Third then: From second then   --- then参数值:来自第二个then的返回值,没有返回值为undefined
 * Third finally: undefined       --- finally没有参数,为undefined
 */

case6_reject引发多then、catch、finally有return

function testPromise6(val) {
  return new Promise((resolve, reject) => {
    reject('失败!')
    // 以下为第一次then、catch、finally
  })
    .then((res) => {
      console.log('First then:', res)
      return 'From first then'
    })
    .catch((err) => {
      console.log('First catch:', err)
      return 'From first catch'
    })
    .finally((res) => {
      console.log('First finally:', res)
      return 'From first finally'
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
      return 'From second then'
    })
    .catch((err) => {
      console.log('Second catch:', err)
      return 'From second catch'
    })
    .finally((res) => {
      console.log('Second finally:', res)
      return 'From second finally'
      // 以下为第三次then、catch、finally
    })
    .then((res) => {
      console.log('Third then:', res)
      return 'From third then'
    })
    .catch((err) => {
      console.log('Third catch:', err)
      return 'From third catch'
    })
    .finally((res) => {
      console.log('Third finally:', res)
      return 'From third finally'
    })
}
testPromise6()

/**
 * testPromise6 执行结果:
 *
 * First catch: 失败!             --- then参数值:来自promise内部的reject参数
 * First finally: undefined       --- finally没有参数,为undefined
 *
 * Second then: From first then   --- then参数值:来自第一个then的返回值,没有返回值为undefined
 * Second finally: undefined      --- finally没有参数,为undefined
 *
 * Third then: From second then   --- then参数值:来自第二个then的返回值,没有返回值为undefined
 * Third finally: undefined       --- finally没有参数,为undefined
 */

case4、case5、case6结论:

  1. 第一次then|catch、finally执行的是promise内部的结果
  2. 第一次then|catch的参数来自promise内部的resolve、reject,finally无参数
  3. 第二次及以后的then一定会执行,参数来自上一个then的返回值,无返回值为undefined
  4. 第二次及以后的finally一定会执行,无参数,为undefined

case7_new Error

function testPromise7(val) {
  return new Promise((resolve, reject) => {
    resolve('成功!')
    // 以下为第一次then、catch、finally
  })
    .then((res) => {
      console.log('First then:', res)
      return new Error('From first then')
    })
    .catch((err) => {
      console.log('First catch:', err)
      return 'From first catch'
    })
    .finally((res) => {
      console.log('First finally:', res)
      return new Error('From first finally')
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
      return 'From second then'
    })
    .catch((err) => {
      console.log('Second catch:', err)
      return 'From second catch'
    })
    .finally((res) => {
      console.log('Second finally:', res)
      return 'From second finally'
      // 以下为第三次then、catch、finally
    })
    .then((res) => {
      console.log('Third then:', res)
      return 'From third then'
    })
    .catch((err) => {
      console.log('Third catch:', err)
      return 'From third catch'
    })
    .finally((res) => {
      console.log('Third finally:', res)
      return 'From third finally'
    })
}
testPromise7()

/**
 * testPromise7 执行结果:
 *
 * First then: 成功!
 * First finally: undefined
 * Second then: Error: From first then at ...
 * Second finally: undefined
 * Third then: From second then
 * Third finally: undefined
 */

case8_throw Error

function testPromise8(val) {
  return new Promise((resolve, reject) => {
    resolve('成功!')
    reject('失败!')
    // 以下为第一次then、catch、finally
  })
    .then((res) => {
      console.log('First then:', res)
      // return new Error('From first then')
      throw new Error('From first then')
    })
    .catch((err) => {
      console.log('First catch:', err)
      return 'From first catch'
    })
    .finally((res) => {
      console.log('First finally:', res)
      return new Error('From first finally')
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
      return 'From second then'
    })
    .catch((err) => {
      console.log('Second catch:', err)
      return 'From second catch'
    })
    .finally((res) => {
      console.log('Second finally:', res)
      return 'From second finally'
      // 以下为第三次then、catch、finally
    })
    .then((res) => {
      console.log('Third then:', res)
      return 'From third then'
    })
    .catch((err) => {
      console.log('Third catch:', err)
      return 'From third catch'
    })
    .finally((res) => {
      console.log('Third finally:', res)
      return 'From third finally'
    })
}
testPromise8()

/**
 * testPromise8 执行结果
 *
 * First then: 成功!
 * First catch: Error: From first then at ...
 * First finally: undefined
 * Second then: From first catch
 * Second finally: undefined
 * Third then: From second then
 * Third finally: undefined
 */

case7、case8结论:

  1. 第二次及以后的then中如果return Error,会被下一个then作为参数输出,finally始终无参数。只会影响下一个,不会影响下下个。
  2. 第二次如果是throw Error,则会被当前的catch语句所捕获
  3. return Error只是作为一个常规的报错返回,而throw则是直接抛出异常

case9_then回调两个参数return Error

function testPromise9(val) {
  return new Promise((resolve, reject) => {
    resolve('成功!')
    // 以下为第一次then、catch、finally
  })
    .then(
      (res) => {
        console.log('First then:', res)
        throw new Error('From first then')
      },
      (err) => {
        console.log('First catch1:', err)
        return 'From first catch2'
      }
    )
    .catch((err) => {
      console.log('First catch2:', err)
      return 'From first catch2'
    })
    .finally((res) => {
      console.log('First finally:', res)
      return new Error('From first finally')
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
      return 'From second then'
    })
    .catch((err) => {
      console.log('Second catch:', err)
      return 'From second catch'
    })
    .finally((res) => {
      console.log('Second finally:', res)
      return 'From second finally'
    })
}
testPromise9()

/**
 * testPromise9 执行结果:
 *
 * First then: 成功!
 * First catch2: Error: From first then at ...
 * First finally: undefined
 * Second then: From first catch2
 * Second finally: undefined
 */

case10_then回调两个参数throw Error

function testPromise10(val) {
  return new Promise((resolve, reject) => {
    reject('失败!')
  })
    .then(
      (res) => {
        console.log('First then:', res)
      },
      (err) => {
        console.log('First catch1:', err)
        // return 'From first catch2'
        throw new Error('From first catch1')
      }
    )
    .catch((err) => {
      console.log('First catch2:', err)
      return 'From first catch2'
    })
    .finally((res) => {
      console.log('First finally:', res)
      return new Error('From first finally')
      // 以下为第二次then、catch、finally
    })
    .then((res) => {
      console.log('Second then:', res)
      return 'From second then'
    })
    .catch((err) => {
      console.log('Second catch:', err)
      return 'From second catch'
    })
    .finally((res) => {
      console.log('Second finally:', res)
      return 'From second finally'
    })
}
testPromise10()
/**
 * testPromise10 执行结果:
 *
 * First catch1: 失败!
 * First catch2: Error: From first then at ...
 * First finally: undefined
 * Second then: From first catch2
 * Second finally: undefined
 */

case11_then回调三个参数

function testPromise11 (val) {
	return new Promise((resolve, reject) => {
    reject('失败!')
    resolve('成功!')
	}).then(res => {
		console.log('First then:', res)
	}, err => {
    console.log('First catch1:', err)
  }, () => {
    console.log('First finally1:', err)
  }).catch(err => {
		console.log('First catch2:', err)
	}).finally(res => {
		console.log('First finally2:', res)
	})
}
testPromise11()
/**
 * 执行结果
 * 
 * First catch1: 失败!
 * First finally2: undefined
 */

case9、case10结论:

  1. 在then中连续写两个回调,第一个参数为then,第二个参数为catch,在then后面再写一个catch。
  2. 如果是resolve,在then的第一个参数中throw Error,会被下一个catch所捕获
  3. 如果是reject,在then的第二个参数中throw Error,会被下一个catch所捕获
  4. 即:then...catch可以将两个回调都赋给then,直接写两个参数,then后面的catch会被当前其他的catch,只有前面的then内部抛出异常才会执行。