site infoHacknerd | Tech Blog
blog cover

🗺️ [ECMAScript6] 17. Promise对象

ES6JavaScript

Promise含义

基本用法

Promise.prototype.then

会返回新的Promise对象(返回的不是原来Promise实例,因此可以链式调用)

Promise.prototype.catch

Promise.prototype.finally

等同于

javascriptCopy
promise
.finally(() => {
  // 语句
});

// 等同于
promise
.then(
  result => {
    // 语句
    return result;
  },
  error => {
    // 语句
    throw error;
  }
);

Promise.all

Promise.race

有一个Promise率先完成,包装实例的状态也会跟着改变。

应用:请求响应超时

javascriptCopy
const p = Promise.race([
  fetch('/resource-that-may-take-a-while'),
  new Promise(function (resolve, reject) {
    setTimeout(() => reject(new Error('request timeout')), 5000)
  })
]);

p
.then(console.log)
.catch(console.error);

上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。

Promise.any

只要有一个Promise变成fulfilled 包装实例会变成fulfilled状态。所有Promise状态变成rejected包装实例状态会变成 rejected。

Promise.allSettled

用于确定所有异步操作都结束了,不管里面的Promise状态是fulfilled 还是rejected,都会出发回掉

Promise.resolve

需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用。

等价于

javascriptCopy
new Promise(resolve => resolve())

resolve参数

  • 1.实例。返回实例
  • javascriptCopy
    Promise.resolve(new String('1')).then(a => console.log(a))
    // String {'1'}

  • 1.thenable对象 (含有then 方法的对象),会将这个对象转化为Promise 并立即执行then()方法返回数据
  • javascriptCopy
    let thenable = {
      then: function(resolve, reject) {
        resolve(42);
      }
    };
    
    let p1 = Promise.resolve(thenable);
    p1.then(function (value) {
      console.log(value);  // 42
    });

  • 1.非thenable对象或者不是对象(原始值)。会返回一个新的Promise对象,状态为resolved
  • javascriptCopy
    Promise.resolve(1).then(a => console.log(a))
    // 1

  • 1.不带参数。立刻返回resolved状态的对象
  • Promise.reject

    生成一个 Promise 对象的实例p,状态为rejected,回调函数会立即执行(本轮“事件循环”(event loop)的结束时执行)。

    javascriptCopy
    Promise.reject('').catch(() => console.log('456'));
    console.log('123');
    // 123
    // 456

    等价于

    javascriptCopy
    new Promise((_resolve, reject) => reject())

    应用

    Promise.try[提案]

    实战中有种情况:是不想去分函数F 是同步还是异步函数,但都想用Promise去处理数据用 catch。来捕获异常。一般会采用下面的做法。

    javascriptCopy
    const f = () => console.log('now');
    Promise.resolve().then(f);
    console.log('next');
    // next
    // now

    但这有个问题。如果函数F 是同步函数,但这样处理之后却变成异步执行了(在本轮事件循环末尾执行)。

    有没有一种方法,让同步函数同步执行,异步函数异步执行,并且让它们具有统一的 API 呢?回答是可以的,并且还有两种写法。

    javascriptCopy
    const f = () => console.log('now');
    (async () => f())();
    console.log('next');
    // now
    // next

    javascriptCopy
    const f = () => console.log('now');
    (() => new Promise(resolve=> resolve(f)))
    .then(...)
    .catch(...)

    使用Promise.try统一捕捉同步和异步错误 。比如,连接数据库函数可能会抛出同步错误(比如连接数据库异常等)或者异步返回数据。

    javascriptCopy
    Promise.try(()=>database.usrs.get({id: userId}))
    .then(...)
    .catch(...)

    Contents

    • Promise含义
    • 基本用法
    • Promise.prototype.then
    • Promise.prototype.catch
    • Promise.prototype.finally
    • Promise.all
    • Promise.race
    • Promise.any
    • Promise.allSettled
    • Promise.resolve
    • Promise.reject
    • 应用
    • Promise.try[提案]

    2024/03/21 06:19