promise

119 阅读2分钟

异步方法实现同步

需求:现在有fnA、fnB、fnC三个异步方法(可类比异步请求),fnB需要fnA结束才能调用,fnC需要fnB结束才能调用

  • async/await 简单粗暴,墙裂推荐!
async function async_await() {
  const resA = await fnA()
  const resB = await fnB()
  const resC = await fnC()
}
  • promise
console.log(`方法A开始...`)
new Promise(fnA)
.then(resA => {
  console.log(`方法A结果:`, resA, `方法B开始...`)
  return new Promise(fnB)
}).then(resB => {
  console.log(`方法B结果:`, resB, `方法C开始...`)
  return new Promise(fnC)
}).then(resC => {
  console.log(`方法C结果:`, resC)
})

const fnA = (resolve, reject) => {
  setTimeout(() => {
    console.log(`方法A完成`)
    resolve(`方法A_data`)
  }, 3000)
}

const fnB = (resolve, reject) => {
  setTimeout(() => {
    console.log(`方法B完成`)
    resolve(`方法B_data`)
  }, 3000)
}

const fnC = (resolve, reject) => {
  setTimeout(() => {
    console.log(`方法C完成`)
    resolve(`方法C_data`)
  }, 3000)
}

reject,then的第二个回调函数,catch

总结:

  • then有两个回调,promise.then(onCompleted, onRejected),promise里resolve则执行onCompleted,reject则执行onRejected
  • reject 是 Promise 的方法,而 catch 是 Promise 实例的方法
  • reject 是用来抛出异常,then的第二个回调函数和catch 是用来处理异常
  • promise内reject后的东西,一定会进入then中的第二个回调,且不会中止链式调用之后的代码执行;如果then中没有写第二个回调,则进入catch,且会中止链式调用之后的代码执行
  • 网络异常(比如断网),会直接进入catch而不会进入then的第二个回调

没有then的第二个回调函数

现在在第二个promise(fnB)中使用reject抛出,我们可以在整个链的最后添加catch。可以看到resolve的promose正常执行,直到链中的某个promise执行了reject,则会跳过后边所有链式调用,直接执行catch

console.log(`方法A开始...`)
new Promise((resolve, reject) => {
  setTimeout(() => {
    //fnA()
    console.log(`方法A成功`)
    resolve('方法A_data')
  }, 3000)
}).then(resA => {
  console.log(`方法B开始...`)
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      //fnB()
      console.log(`方法B失败`)
      reject(`方法B_reason`)
    }, 3000)
  })
}).then(resB => console.log(`方法B结果:`, resB))
  .catch(err => console.log(`err`, err))

//打印结果
//方法A开始...
//方法A成功
//方法B开始...
//方法B失败
//err 方法B_reason

有then的第二个回调函数

我们现在定义一个then的第二个参数

const onRejected = resson => console.log('resson: ', resson);

这次让第一个promise(fnA)执行reject,在对应的then中添加我们定义的第二个参数onRejected。可以看到onRejected执行了,catch没有执行,而且注意,之后的链式调用并没有中止

console.log(`方法A开始...`)
new Promise((resolve, reject) => {
  setTimeout(() => {
    //fnA()
    console.log(`方法A失败`)
    reject('方法A失败_reason')
  }, 3000)
}).then(
  resA => {
    console.log(`方法B开始...`)
    return new Promise((resolve, reject) => {
      setTimeout(() => {
        //fnB()
        console.log(`方法B成功`)
        resolve(`方法B_data`)
      }, 3000)
    })
  },
  onRejected
).then(resB => console.log(`方法B结果:`, resB))
  .catch(err => console.log(`err`, err))

// 打印结果
// 方法A开始...
// 方法A失败
// resson:  方法A失败_reason
// 方法B结果: undefined