Promise的这些使用方法你会吗

251 阅读3分钟
  1. Promise自定义一个定时器
function timeout(delay = 1000) {
  return new Promise((resolve) => setTimeout(resolve, delay));
}

timeout(1000)
  .then((v) => {
    console.log(11);
    return timeout(1000);
  })
  .then((v) => {
    console.log(22);
  });
  1. Promise.resolve(value) 快速返回一个Promise,结果值由value的值决定
  • value的值是 thenable(即,带有then方法的对象)的情况,返回Promsie对象由then 的执行情况:
let p1 = Promise.resolve(
  new Promise((resolve, reject) => {
    // reject(333); // p2 为一个失败的Promise
    resolve(333); // p2 为一个成功的Promise
  })
);
console.log(p1);

或者是传递一个带then 方法的对象

let foo = {
    then(resolve, reject) {
        resolve(222);
    }
}

let p2 = Promise.resolve(foo)
p2.then(v=>{
    console.log(v);
})
  • 其他情况返回的是成功状态的Promise对象:
// let p3 = Promise.resolve(123);//传递的参数可以是基本类型、Object、甚至是undefined,p3 返回的都是一个成功的Promise
let p3 = Promise.resolve(new Date());

  1. Promise.reject(value) 返回一个失败状态的Promise对象
let p1 = Promise.reject("error");
p1.then(
  (v) => {
    console.log(v);
  },
  (reason) => {
    console.log('faile:' + reason);
  }
);

打印的结果为 faile:error

使用场景:在一个Promise的回调中根据条件判断是否成功,如果不成功,可以直接使用Promise.reject()方法

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve("success");
  }, 1000);
})
  .then((v) => {
      //根据条件判断是否成功
    if (v != "success") {
      return Promise.reject("执行失败");
    }
    return "执行成功";
  })
  .catch((e) => {
    console.log("fail:" + e);
  });
  1. Promise.all(values) 返回一个新的Promise对象,传递的values 为Promise 对象数组,当数组中的Promise对象都成功时,返回成功的是一个成功的Promise数组,里面的值是values 执行成功的结果,当values中有一个失败时,返回失败的Promise,值为失败的Promise返回的值。
let p1 = Promise.resolve(11);
let p2 = new Promise((resolve, rejcct) => {
  setTimeout(() => {
    resolve(22);
  }, 1000);
});

Promise.all([p1, p3]).then(
  (values) => {
    console.log(values);
  },
  (reason) => {
    console.log(reason);
  }
);

打印的结果是一个数组

image.png

有个细节需要注意,假如失败的结果已经进行处理,则Promise.all 返回的就是所有成功的结果 和 错误处理完毕的结果,看如下的例子:

let p2 = new Promise((resolve, rejcct) => {
  setTimeout(() => {
    // resolve(22);
    rejcct("fail");
  }, 1000);
}).catch((e) => {
  return e + "已经处理错误";
});
let p3 = Promise.resolve(11);

Promise.all([p2, p3]).then((results) => {
  console.log(results);
});

打印的结果:

image.png

  1. Promise.allSettled(values) 传递的值values为一个包含Promise的对象的集合,等到所有values 中的值都已settled(敲定),values中每个Promise对象都已经返回成功(fulfilled)或失败(rejected)后返回一个结果值results,结果results中的值对应values中的每个结果。
let p1 = Promise.resolve(11);
let p2 = Promise.reject("error");
let p3 = new Promise((resolve, rejcct) => {
  setTimeout(() => {
    resolve(22);
  }, 1000);
});


Promise.allSettled([p1, p2, p3])
  .then((results) => {
    console.log(results);
    //可以过滤一下 返回给后面的then 使用
    return results.filter((v) => {
      return v.status == "fulfilled";
    });
  })
  .then((arr) => {
    console.log(arr);
  });

打印的结果

image.png

  1. Promise.any(values) values 为一个Promise对象集合,返回的结果result为values中最先settle(敲定)成功(fulfilled)状态的结果
let p1 = Promise.reject("error");
let p2 = new Promise((resolve, rejcct) => {
  setTimeout(() => {
    resolve(22);
  }, 1000);
});
let p3 = Promise.resolve(11);

Promise.any([p1, p2, p3]).then((val) => {
  console.log(val); //最先执行成功的是p3,所以打印的结果是11
});
  1. Promise.race(values) values 为一个Promise对象的集合,返回的结果由最先settled(敲定)的Promise决定,(不管成功(fulfilled)或失败(rejected),只要是第一个执行结束就会返回结果)
let p1 = Promise.reject("error");
let p2 = new Promise((resolve, rejcct) => {
  setTimeout(() => {
    resolve(22);
  }, 1000);
});
let p3 = Promise.resolve(11);

Promise.race([p1, p2, p3]).then(
  (v) => {
    console.log(v);
  },
  (reason) => {
    console.log("fail:" + reason);
  }
);

p1最先返回失败的结果,所以打印的结果是fail:error

  1. Promise 队列 如何利用Promise,打印一个数组中每一个元素,每秒钟打印一个
function myPrint(num) {
  let p1 = Promise.resolve();

// 使用map
//   num.map((v) => {
//     p1 = p1.then((_) => {
//       return new Promise((resolve) => {
//         setTimeout(() => {
//           console.log(v);
//           resolve();
//         }, 1000);
//       });
//     });
//   });

//使用for 循环
  for (let i = 0; i < num.length; i++) {
    let val = num[i];
    p1 = p1.then((_) => {
      return new Promise((resolve) => {
        setTimeout(() => {
          console.log(val);
          resolve();
        }, 1000);
      });
    });
  }
}

let num = [1, 2, 3, 4, 5];
myPrint(num);

Promise 队列的应用:在实际开发中有时候我们需要先获取一个网络请求后再去进行另一个网络请求,这时候我们可以使用Promise队列

import "./ajax";// ajax 是自己用Promise封装的网络请求库

function getUserInfo(url) {
  return ajax(url).then((val) => {
    console.log(val);
  });
}

function getOtherInfo(url) {
  return ajax(url).then((val) => {
    console.log(val);
  });
}

function quary(promises) {
  let p = Promise.resolve();
  promises.map((v) => {
    p = p.then((_) => {
      return p();
    });
  });
}

quary([getUserInfo("https://xxxx"), getOtherInfo("https://xxx")]);