轻松理解Promise.all 、Promise.then、Promise.race有什么区别以及使用方法

简单来说呢,Promse.all一般应用于某个场景需要多个接口数据合并起来才能实现

有个极大地好处我必须说一下,请求顺序和获取数据顺序是一样的哟,大可放心使用~~

const success1 = new Promise((res,rej) => {
  const data = {status: 'success', message:'success1'}
  res(data)
})
const error1 = new Promise((res,rej) => {
  const data = {status: 'error', message:'error1'}
  rej(data.message)
})
const success2 = new Promise((res,rej) => {
  const data = {status: 'success', message:'success2'}
  res(data)
})
const error2 = new Promise((res,rej) => {
  const data = {status: 'error', message:'error2'}
  rej(data)
})
Promise.all([success1, success2]).then(res => {
  console.log('Promise.all([success1, success2]).then')
  console.log(res)
}).catch(error => {
  console.log('Promise.all([success1, success2]).catch')
  console.log(error)
})

// 打印结果
// Promise.all([success1, success2]).then
// 0: {status: "success", message: "success1"}
// 1: {status: "success", message: "success2"}
// length: 2
// __proto__: Array(0)


Promise.all([success1, error1, success2]).then(res => {
  console.log('Promise.all([success1, error1, success2]).then')
  console.log(res)
}).catch(error => {
  console.log('Promise.all([success1, error1, success2]).catch')
  console.log(error)
})

// 打印结果
// Promise.all([success1, error1, success2]).catch
// error1


Promise.all([success1, error1, success2, error2]).then(res => {
  console.log('Promise.all([success1, error1, success2, error2]).then')
  console.log(res)
}).catch(error => {
  console.log('Promise.all([success1, error1, success2, error2]).catch')
  console.log(error)
})

// 打印结果
// Promise.all([success1, error1, success2, error2]).catch
// error1

总结:按照上面的使用方法

所有结果成功>按顺序返回成功

有一个失败>返回第一个失败的那个

重点来了~~ 解决有一个失败就全盘失败的方法如下

Promise.all(
  [
  success1.catch(err=>err), 
  error1.catch(err=>err), 
  success2.catch(err=>err), 
  error2.catch(err=>err)
  ]
  )
    .then((res) => {
      console.log(res)
      if (res[0] && res[0].status == 'success') {
        console.log('res[0]success', res[0])
      } else {
        console.log('res[0]error', res[0])
      }
      if (res[1] && res[1].status == 'success') {
        console.log('res[1]success', res[1])
      } else {
        console.log('res[1]error', res[1])
      }
      if (res[2] && res[2].status == 'success') {
        console.log('res[2]success', res[2])
      } else {
        console.log('res[2]error', res[2])
      }
      if (res[3] && res[3].status == 'success') {
        console.log('res[3]success', res[3])
      } else {
        console.log('res[3]error', res[3])
      }
    })

    // 打印结果
    // res[0]success {status: "success", message: "success1"}
    // res[1]error error1
    // res[2]success {status: "success", message: "success2"}
    // res[3]error {status: "error", message: "error2"}

来说一下Promise.prototype.then

下个请求依赖上个请求获取的数据


  function P1() {
    return new Promise((res, rej) => {
      const data = { status: 'success', message: 'res2依赖的数据' }
      setTimeout(() => {
        res(data)
      }, 1000)
    })
  }
  function P2(params) {
    return new Promise((res, rej) => {
      const data = { status: 'success', message: 'res3依赖的数据', r: params }
      setTimeout(() => {
        res(data)
      }, 2000)
    })
  }
  function P3(params) {
    return new Promise((res, rej) => {
      const data = { status: 'success', message: '最终结果', r: params }
      setTimeout(() => {
        res(data)
      }, 3000)
    })
  }
  try {
    P1()
      .then((res) => P2(res))
      .then((res) => P3(res))
      .then((res) => {
        console.log(JSON.stringify(res))
      })
  } catch (e) {
    console.log('执行请求出错', e)
  }

  // 打印结果
  // {
  //   status: 'success',
  //   message: '最终结果',
  //   r: {
  //     status: 'success',
  //     message: 'res3依赖的数据',
  //     r: { status: 'success', message: 'res2依赖的数据' },
  //   },
  // }

最后来看一下Promise.race,简单来说就是几个请求比赛跑步,看谁跑得快,跑的最快的就会被直接返回,不论成功还是失败.

let suc1 = new Promise((res, rej) => {
    setTimeout(() => {
      res('success1000')
    }, 1000)
  })
  let suc2 = new Promise((res, rej) => {
    setTimeout(() => {
      res('success1500')
    }, 1500)
  })

  let err1 = new Promise((res, rej) => {
    setTimeout(() => {
      rej('failed500')
    }, 500)
  })
  let err2 = new Promise((res, rej) => {
    setTimeout(() => {
      rej('failed500')
    }, 2000)
  })

  Promise.race([suc1, err1])
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })

  // 打印结果
  // failed500

  Promise.race([suc1, suc2, err2])
    .then((result) => {
      console.log(result)
    })
    .catch((error) => {
      console.log(error)
    })
    
  // 打印结果
  // success1000

附promise.race源码,

重点:Constructor.resolve(entries[i]).then(resolve, reject);

通过循环promise 最终的resolve接收为同一个

function race(entries) {
/*jshint validthis:true */
var Constructor = this; // this 是调用 race 的 Promise 构造器函数。

if (!isArray(entries)) {
return new Constructor(function (_, reject) {
return reject(new TypeError('You must pass an array to race.'));
});
} else {
return new Constructor(function (resolve, reject) {
var length = entries.length;
for (var i = 0; i < length; i++) {
Constructor.resolve(entries[i]).then(resolve, reject);
}
});
}
}

总结:由此可以看到,我们可以用它来

1.测试接口的响应速度

2.当用户信号不好的时候可以发出网络不好的提示信息

3.后端代码部署了很多服务器,我们可以看哪个速度快就用哪个的数据

欢迎路过的小伙伴们继续补充哦~~

结语

欢迎大家指出文章需要改正之处~
如果有更好的方法,欢迎大家提出来,共同进步哟~~

原文地址:https://www.cnblogs.com/sugartang/p/14348391.html