← 返回目录

Promise

Promise 是处理异步操作的东西:成功走 then,失败走 catch,不用再回调套回调。

1. 以前写异步是什么样(回调地狱)

以前 · 一层套一层 现在 · Promise 排队
setTimeout(function () {
  console.log("第一步");
  setTimeout(function () {
    console.log("第二步");
    setTimeout(function () {
      console.log("第三步");
    }, 300);
  }, 300);
}, 300);
new Promise((resolve) => {
  setTimeout(() => {
    console.log("第一步");
    resolve();       // 完成了,继续下一步
  }, 300);
})
.then(() => {
  console.log("第二步");
})
.then(() => {
  console.log("第三步");
});

以前一层套一层,越套越乱(叫"回调地狱");Promise 把每一步"排队"排开,一行一步,清清楚楚。

2. Promise 的三个状态

pending   —— 等待中(还没出结果)
fulfilled —— 成功
rejected  —— 失败
	

就像一个外卖订单——刚下单是"等待中",做好了是"成功",做砸了是"失败"。

3. 成功和失败分开写

以前 · 挤在一个回调里 现在 · then / catch 分开
function getData(cb) {
  setTimeout(() => {
    let ok = false;
    if (ok) cb(null, "数据");
    else cb("出错了");
  }, 300);
}
getData((err, data) => {
  if (err) console.log("失败:", err);
  else console.log("成功:", data);
});
let p = new Promise((resolve, reject) => {
  setTimeout(() => {
    let ok = false;
    if (ok) resolve("数据");     // 成功
    else reject("出错了");       // 失败
  }, 300);
});
p.then(data => console.log("成功:", data))
 .catch(err => console.log("失败:", err));

成功交给 then,失败交给 catch,各管各的,不像以前所有情况挤在一个回调里判断。

4. 真实用法:把异步操作包起来

function delay(ms) {
  return new Promise(resolve => {
    setTimeout(resolve, ms);   // 等 ms 毫秒后算成功
  });
}

delay(1000).then(() => {
  console.log("1 秒后执行");
});

把"等 1 秒"这件异步的事包成 Promise,外面用 then 接住。真实项目里就是用这个思路包 Ajax 请求、读文件、加载图片等。

5. 注意:状态一旦固定就不能改

let p = new Promise((resolve, reject) => {
  resolve("第一次");    // 先成功了
  reject("第二次");     // 没用,状态已经固定
});
p.then(v => console.log(v));   // 第一次

订单一旦"成功 / 失败"就定了,后面再改不了,避免结果反复变。

一句话:Promise = 把"成功怎么办"和"失败怎么办"分开写的异步工具