有学有练才叫学习:学而不思则罔,思而不学则殆:学而不习,纸上谈兵,习而不进,画地为牢!

promise api(Promise 的相关概念 与API 详情解释)

javascript 炮渣日记 2周前 (11-15) 15次浏览 已收录 0个评论 扫描二维码
promise api(Promise 的相关概念 与API 详情解释)

Promise.all()

当我们在代码中需要使⽤异步流程控制时,可以通过Promise.then来实现让异步流程⼀个接⼀个的执⾏,假设实际案例中,某个模块的⻚⾯需要同时调⽤3个服务端接⼝,并保证三个接⼝的数据全部返回后,才能渲染⻚⾯。这种情况如果a接⼝耗时1s、b接⼝耗时0.8s、c接⼝耗时1.4s,如果只⽤Promise.then来执⾏流程控制,可以保证三个接⼝按顺序调⽤结束再渲染⻚⾯,但是如果通过then函数的异步控制,必须等待每个接⼝调⽤完毕才能调⽤下⼀个,这样总耗时就是1+0.8+1.4 = 3.2s。这种累加显然增加了接⼝调⽤的时间消耗,所以Promise提供了⼀个all⽅法来解决这个问题。

Promise.all([promise对象,promise对象,...]).then(回调函数)

回调函数的参数是⼀个数组,按照第⼀个参数的promise对象的顺序展示每个promise的返回结果。我们可以借助Promise.all来实现,等最慢的接⼝返回数据后,⼀起得到所有接⼝的数据,那么这个耗时将会只会按照最慢接⼝的消耗时间1.4s执⾏,总共节省了1.8s,参考代码如下:

//promise.all相当于统⼀处理了
//多个promise任务,保证处理的这些所有promise
//对象的状态全部变成为fulfilled之后才会出发all的
//.then函数来保证将放置在all中的所有任务的结果返回
let p1 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve('第⼀个promise执⾏完毕')
  },1000)
})

let p2 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve('第⼆个promise执⾏完毕')
  },2000)
})

let p3 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve('第三个promise执⾏完毕')
  },3000)
})

Promise.all([p1,p3,p2]).then(res => {
  console.log(res)
}).catch(function(err){
  console.log(err)
})
promise api(Promise 的相关概念 与API 详情解释)

并发处理多个异步任务,所有任务都能执行完成才能得到结果。

function queryData(url) {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
      if (xhr.readyState != 4) {
        return;
      }
      if (xhr.readyState == 4 && xhr.status == 200) {
        resolve(xhr.responseText);
      } else {
        reject('服务器错误');
      }
    };
    xhr.open('get', url);
    xhr.send();
  });
}
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a2');
var p3 = queryData('http://localhost:3000/a3');
Promise.all([p1, p2, p3]).then((data) => console.log(data));

Promise.race()

race⽅法与all⽅法使⽤格式相同:

Promise.race([promise对象,promise对象,...]).then(回调函数)

回调函数的参数是前⾯数组中最快⼀个执⾏完毕的promise的返回值。

所以使⽤race⽅法主要的使⽤场景是什么样的呢?举个例⼦,假设我们的⽹站有⼀个播放视频的⻚⾯,通常流媒体播放为了保证⽤户可以获得较低的延迟,都会提供多个媒体数据源。我们希望⽤户在进⼊⽹⻚时,优先展示的是这些数据源中针对当前⽤户速度最快的那⼀个,这时便可以使⽤Promise.race()来让多个数据源进⾏竞赛,得到竞赛结果后,将延迟最低的数据源⽤于⽤户播放视频的默认数据源,这个场景便是race的⼀个典型使⽤场景。

//promise.race()相当于将传⼊的所有任务
//进⾏了⼀个竞争,他们之间最先将状态变成fulfilled的
//那⼀个任务就会直接的触发race的.then函数并且将他的值
//返回,主要⽤于多个任务之间竞争时使⽤
let p1 = new Promise((resolve,reject) => {
  setTimeout(() => {
    resolve('第⼀个promise执⾏完毕')
  },5000)
})

let p2 = new Promise((resolve,reject) => {
  setTimeout(() => {
    reject('第⼆个promise执⾏完毕')
  },2000)
})

let p3 = new Promise(resolve => {
  setTimeout(() => {
    resolve('第三个promise执⾏完毕')
  },3000)
})

Promise.race([p1,p3,p2]).then(res => {
  console.log(res)
}).catch(function(err){
  // 第二个promise执行完毕
  console.error(err)
})
promise api(Promise 的相关概念 与API 详情解释)

并发处理多个异步任务,拿到最快一个完成任务的结果。

function queryData(url) {
  return new Promise(function(resolve, reject) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function() {
      if (xhr.readyState != 4) {
        return;
      }
      if (xhr.readyState == 4 && xhr.status == 200) {
        resolve(xhr.responseText);
      } else {
        reject('服务器错误');
      }
    };
    xhr.open('get', url);
    xhr.send();
  });
}
var p1 = queryData('http://localhost:3000/a1');
var p2 = queryData('http://localhost:3000/a2');
var p3 = queryData('http://localhost:3000/a3');
Promise.race([p1, p2, p3]).then((data) => console.log(data));
喜欢 (0)
炮渣日记
关于作者:
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址