这里用 setTimeout() 模仿异步请求。

const callbackFn = (firstName, callback) => {
  setTimeout(() => {
    if (!firstName) return callback(new Error("no first name passed in!")); // failed

    const fullName = `${firstName} Doe`;

    return callback(fullName); // succeed
  }, 2000);
};

callbackFn("John", console.log);
callbackFn(null, console.log);

Promise 实现如下

const promiseFn = (firstName) => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (!firstName) reject(new Error("no first name passed in!")); // failed

      const fullName = `${firstName} Doe`;

      resolve(fullName); // succeed
    }, 2000);
  });
};

promiseFn("Jane").then(console.log);
promiseFn().catch(console.log);

这里是 Promise 一些需要注意的点

const setDelay = (millisecond) => {
  return new Promise((resolve, reject) => {
    if (typeof millisecond != "number")
      reject(new Error("参数必须是number类型"));
    setTimeout(() => {
      resolve(`我延迟了${millisecond}毫秒后输出的`);
    }, millisecond);
  });
};

const setDelaySecond = (seconds) => {
  return new Promise((resolve, reject) => {
    if (typeof seconds != "number" || seconds > 10)
      reject(new Error("参数必须是number类型,并且小于等于10"));
    setTimeout(() => {
      resolve(`我延迟了${seconds}秒后输出的,是第二个函数`);
    }, seconds * 1000);
  });
};

// Promise chains
// then 式链式写法的本质其实是一直往下传递返回一个新的 Promise,也就是说 then 在下一步接收的是上一步返回的 Promise。
// 处理错误只需要在链式末尾 catch 进行处理就可以。
setDelay(2000)
  .then((result) => {
    console.log(result);
    console.log("我进行到第一步的");
    return setDelaySecond(3);
  })
  .then((result) => {
    console.log("我进行到第二步的");
    console.log(result);
  })
  .catch((err) => {
    console.log(err);
  });
// Promise 中间返回自定义的值只需要用 `retunPromise.resolve()` 处理就可以。
setDelay(2000)
  .then((result) => {
    console.log("第一步完成了");
    console.log(result);
    let message = "这是我自己想处理的值";
    return Promise.resolve(message); // 这里返回我想在下一阶段处理的值
  })
  .then((result) => {
    console.log("第二步完成了");
    console.log(result); // 这里拿到上一阶段的返回值
    //return Promise.resolve('这里可以继续返回')
  })
  .catch((err) => {
    console.log(err);
  });

Links to this note