08月08, 2022

JS进阶(10)--Promise(3)--Promise链式调用与静态方法

Promise链式调用与静态方法

  1. then方法必定会返回一个新的Promise

    可理解为后续处理也是一个任务

  2. 新任务的状态取决于后续处理:

    • 若没有相关的后续处理,新任务的状态和前任务一致,数据为前任务的数据

    • 若有后续处理但还未执行,新任务挂起。

    • 若后续处理执行了,则根据后续处理的情况确定新任务的状态
      • 后续处理执行无错,新任务的状态为完成,数据为后续处理的返回值
      • 后续处理执行有错,新任务的状态为失败,数据为异常对象
      • 后续执行后返回的是一个任务对象,新任务的状态和数据与该任务对象一致

由于链式任务的存在,异步代码拥有了更强的表达力

// 常见任务处理代码

/*
 * 任务成功后,执行处理1,失败则执行处理2
 */
pro.then(处理1).catch(处理2)

/*
 * 任务成功后,依次执行处理1、处理2
 */
pro.then(处理1).then(处理2)

/*
 * 任务成功后,依次执行处理1、处理2,若任务失败或前面的处理有错,执行处理3
 */
pro.then(处理1).then(处理2).catch(处理3)

将之前求职的代码,改为链式调用:

let pro = sendMessage("华为");

pro.then((data) => { 
  if (data.pass) {
    console.log(data.msg);
  }
  else { 
    console.log(data.msg);
    return sendMessage("小米")
  }
}).then(data => { 
  if (!data) return;
  if (data.pass) {
    console.log(data.msg);
  }
  else { 
    console.log(data.msg);
    return sendMessage("京东")
  }
}).then(data => { 
  if (!data) return;
  if (data.pass) {
    console.log(data.msg);
  }
  else { 
    console.log(data.msg);
    return sendMessage("天美")
  }
}).catch(reason => { 
  console.log(reason);
})

[扩展]Promise的静态方法

#

方法名 含义
Promise.resolve(data) 直接返回一个完成状态的任务
Promise.reject(reason) 直接返回一个拒绝状态的任务
Promise.all(任务数组) 返回一个任务
任务数组全部成功则成功
任何一个失败则失败
Promise.any(任务数组) 返回一个任务
任务数组任一成功则成功
任务全部失败则失败
Promise.allSettled(任务数组) 返回一个任务
任务数组全部已决则成功
该任务不会失败,直接返回所有结果(不会走.catch()方法)
Promise.race(任务数组) 返回一个任务
任务数组任一已决则已决,状态和其一致

比如下面的一个场景

帅哥女朋友出门时,交待了给他几个任务:

  1. 做饭

    可交给电饭煲完成

  2. 洗衣服

    可交给洗衣机完成

  3. 打扫卫生

    可交给扫地机器人完成

帅哥需要在所有任务结束后给女朋友汇报工作,哪些成功了,哪些失败了

为了最大程度的节约时间,帅哥希望这些任务同时进行,最终汇总结果统一处理

每个任务可以看做是一个返回Promise的函数

// 做饭
function cook() {
  return new Promise((resolve, reject) => {
    console.log('帅哥打开了电饭煲');
    setTimeout(() => {
      if (Math.random() < 0.5) {
        resolve('饭已ok');
      } else {
        reject('做饭却忘了加水,米饭变成了爆米花');
      }
    }, 2000);
  });
}

// 洗衣服
function wash() {
  return new Promise((resolve, reject) => {
    console.log('帅哥打开了洗衣机');
    setTimeout(() => {
      if (Math.random() < 0.5) {
        resolve('衣服已经洗好');
      } else {
        reject('洗衣服时停水了,洗了个寂寞');
      }
    }, 2500);
  });
}

// 打扫卫生
function sweep() {
  return new Promise((resolve, reject) => {
    console.log('帅哥打开了扫地机器人');
    setTimeout(() => {
      if (Math.random() < 0.5) {
        resolve('地板扫的非常干净');
      } else {
        reject('扫地机器人被哈士奇一爪掀翻了');
      }
    }, 3000);
  });
}

使用allSettled函数:

Promise.allSettled([cook(), wash(), sweep()]).then((result) => {
  //查看result对象状态
  console.log(result);
  // 处理汇总结果
  const report = result
    .map((r) => (r.status === 'fulfilled' ? r.value : r.reason))
    .join(';');
  console.log(report);
});

本文链接:http://www.yanhongzhi.com/post/js_ap_24.html

-- EOF --

Comments