Yasin

Yasin

promise的使用

1. resolvereject 能传什么值

两者都几乎可以传任意 JavaScript 值

  • 基本类型:stringnumberbooleannullundefinedsymbolbigint
  • 对象:普通对象、数组、函数
  • Error 对象
  • 另一个 Promise

例子

resolve("成功");
resolve(123);
resolve({ id: 1, name: "Tom" });
resolve([1, 2, 3]);
resolve(Promise.resolve("嵌套 Promise"));

reject("失败原因");
reject(new Error("请求失败"));
reject({ code: 500, msg: "服务器错误" });

实际开发建议

  • resolve:通常传真正需要的数据
  • reject:通常传 Error 对象,更规范,方便排错
reject(new Error("网络异常"));

2. Promise 是什么

Promise 是 JS 里表示异步操作结果的对象。

它有 3 种状态:

  • pending:等待中
  • fulfilled:已成功
  • rejected:已失败

状态一旦改变,就不能再变。


3. Promise 基本写法

语法:

const p = new Promise((resolve, reject) => {
  // 异步逻辑
  // 成功时调用 resolve(value)
  // 失败时调用 reject(reason)
});

最简单示例

const p = new Promise((resolve, reject) => {
  const ok = true;

  if (ok) {
    resolve("操作成功");
  } else {
    reject("操作失败");
  }
});

4. 怎么接收 resolvereject 传出的值

成功:then

p.then((res) => {
  console.log("成功:", res);
});

失败:catch

p.catch((err) => {
  console.log("失败:", err);
});

不管成功失败:finally

p.finally(() => {
  console.log("结束");
});

5. 完整示例

const p = new Promise((resolve, reject) => {
  setTimeout(() => {
    const ok = true;

    if (ok) {
      resolve({ code: 200, data: ["html", "css", "js"] });
    } else {
      reject(new Error("请求失败"));
    }
  }, 1000);
});

p.then((res) => {
  console.log("成功结果:", res);
})
  .catch((err) => {
    console.log("失败结果:", err.message);
  })
  .finally(() => {
    console.log("请求结束");
  });

6. then 的完整写法

then 其实可以接收两个参数:

p.then(
  (res) => {
    console.log("成功", res);
  },
  (err) => {
    console.log("失败", err);
  },
);

但一般更推荐:

p.then((res) => {
  console.log(res);
}).catch((err) => {
  console.log(err);
});

这样更清晰。


7. Promise 链式调用

then 会返回一个新的 Promise,所以可以链式写:

Promise.resolve(1)
  .then((res) => {
    console.log(res); // 1
    return res + 1;
  })
  .then((res) => {
    console.log(res); // 2
    return res + 1;
  })
  .then((res) => {
    console.log(res); // 3
  });

如果 then 里返回的是普通值

会自动包装成成功的 Promise。

如果 then 里抛错

会进入 catch

Promise.resolve("start")
  .then((res) => {
    throw new Error("中间出错");
  })
  .catch((err) => {
    console.log(err.message); // 中间出错
  });

8. 如果 resolve 传的是 Promise

会“跟随”这个 Promise 的最终结果:

const inner = new Promise((resolve) => {
  setTimeout(() => resolve("最终结果"), 1000);
});

const outer = new Promise((resolve) => {
  resolve(inner);
});

outer.then((res) => {
  console.log(res); // 最终结果
});

9. 常见静态方法

Promise.resolve

快速创建成功 Promise

Promise.resolve("ok").then((res) => {
  console.log(res);
});

Promise.reject

快速创建失败 Promise

Promise.reject(new Error("fail")).catch((err) => {
  console.log(err.message);
});

Promise.all

全部成功才成功,一个失败就失败

Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)]).then(
  (res) => {
    console.log(res); // [1, 2, 3]
  },
);

Promise.race

谁先结束就采用谁的结果

Promise.race([
  new Promise((resolve) => setTimeout(() => resolve("A"), 1000)),
  new Promise((resolve) => setTimeout(() => resolve("B"), 500)),
]).then((res) => {
  console.log(res); // B
});

Promise.allSettled

不管成功失败,全部结束后统一返回

Promise.allSettled([Promise.resolve("成功"), Promise.reject("失败")]).then(
  (res) => {
    console.log(res);
  },
);

Promise.any

谁先成功就返回谁,全部失败才失败

Promise.any([
  Promise.reject("A"),
  Promise.resolve("B"),
  Promise.resolve("C"),
]).then((res) => {
  console.log(res); // B
});

10. Promise 和 async/await

async/await 本质上是 Promise 的语法糖。

function getData() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({ list: [1, 2, 3] });
    }, 1000);
  });
}

async function main() {
  try {
    const res = await getData();
    console.log(res);
  } catch (err) {
    console.log(err);
  } finally {
    console.log("结束");
  }
}

main();

11. 实际请求示例

function requestUser() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      const success = true;

      if (success) {
        resolve({
          code: 200,
          data: {
            id: 1,
            name: "Alice",
          },
        });
      } else {
        reject(new Error("获取用户信息失败"));
      }
    }, 1000);
  });
}

requestUser()
  .then((res) => {
    console.log("用户信息:", res.data);
  })
  .catch((err) => {
    console.log("错误:", err.message);
  });

12. 一句话总结

  • resolve(value):传成功结果
  • reject(reason):传失败原因
  • then/catch/finally 消费结果
  • async/await 是 Promise 的更简洁写法

如果需要,可以下一步继续讲 then 为什么能链式调用手写一个简化版 Promise