三个状态

Promises/A+ 规范

promise对象

then 方法链式实现

  1. promise =
  2. {
  3. then: function(callback) {
  4. callback();
  5. }
  6. }

手写实现

:::info 使用 hack 先实现 resolve 时,callback 已经经过 then 中 callback = cb :::

  1. function Promise(fn) {
  2. var callback = null;
  3. this.then = function (cb) {
  4. callback = cb;
  5. };
  6. function resolve(value) {
  7. setTimeout(function () {
  8. // hack
  9. callback(value);
  10. }, 0);
  11. }
  12. fn(resolve);
  13. }
  14. var p = new Promise((resolve) => {
  15. resolve(666);
  16. }).then((data) => {
  17. console.log("Got a value: " + data);
  18. });

:::info 使用 promise 状态,不使用 hack 方法 :::

  1. function Promise(fn) {
  2. var state = "pending";
  3. var value;
  4. this.then = function (onResolved) {
  5. handle(onResolved);
  6. };
  7. function resolve(newValue) {
  8. value = newValue; // value -> 666
  9. state = "resolved"; // pending -> resolved
  10. }
  11. function handle(onResolved) {
  12. onResolved(value);
  13. }
  14. fn(resolve); // 在 new 的时候执行 resolve
  15. }
  16. var p = new Promise((resolve) => {
  17. resolve(666);
  18. }).then((data) => {
  19. console.log("Got a value: " + data);
  20. });

:::info 实现链式操作,每个 then 都会返回 promise 对象 :::

  1. function Promise(fn) {
  2. var state = "pending";
  3. var value;
  4. function resolve(newValue) {
  5. value = newValue;
  6. state = "resolved";
  7. }
  8. function handle(handler) {
  9. if (!handler.onResolved) { // 处理只调用 then 没传 onResolved 函数,让下一个 then 可以接
  10. handler.resolve(value);
  11. return;
  12. }
  13. var returnValue = handler.onResolved(value);
  14. handler.resolve(returnValue);
  15. }
  16. this.then = function (onResolved) {
  17. return new Promise(function (resolve) { // 每个 then 都会返回 promise 对象
  18. handle({
  19. onResolved: onResolved,
  20. resolve: resolve,
  21. });
  22. });
  23. };
  24. fn(resolve);
  25. }
  26. var p = new Promise((resolve) => {
  27. resolve(666);
  28. })
  29. .then()
  30. .then((data) => {
  31. console.log("Got a value: " + data);
  32. return 88;
  33. })
  34. .then((secondResult) => {
  35. console.log(secondResult);
  36. });

:::info 处理 then 返回 promise 而不是 原始值 的情况,用 then 即可以取回值 :::

  1. function Promise(fn) {
  2. var state = "pending";
  3. var value;
  4. function resolve(newValue) {
  5. value = newValue;
  6. state = "resolved";
  7. }
  8. function handle(handler) {
  9. if (!handler.onResolved) {
  10. handler.resolve(value);
  11. return;
  12. }
  13. var returnValue = handler.onResolved(value);
  14. handler.resolve(returnValue);
  15. }
  16. this.then = function (onResolved) {
  17. return new Promise(function (resolve) {
  18. handle({
  19. onResolved: onResolved,
  20. resolve: resolve,
  21. });
  22. });
  23. };
  24. fn(resolve);
  25. }
  26. function doSomething() {
  27. return new Promise(function (resolve) {
  28. resolve(666);
  29. });
  30. }
  31. function doSomethingElse(value) {
  32. return new Promise(function (resolve) {
  33. resolve("did something else with " + value);
  34. });
  35. }
  36. var p = doSomething()
  37. .then()
  38. .then((data) => {
  39. console.log("Got a value: " + data);
  40. return doSomethingElse(data);
  41. })
  42. .then((anotherPromise) => {
  43. anotherPromise.then(function(value){ // 如果是返回的是 promise 还要用 then
  44. console.log("Got anotherPromise: " + value);
  45. })
  46. });
  1. function Promise(fn) {
  2. var state = "pending";
  3. var value;
  4. function resolve(newValue) {
  5. if (newValue && typeof newValue.then === "function") { // 递归处理 resolve return 是 promise
  6. newValue.then(resolve);
  7. return;
  8. }
  9. value = newValue;
  10. state = "resolved";
  11. }
  12. function handle(handler) {
  13. if (!handler.onResolved) {
  14. handler.resolve(value);
  15. return;
  16. }
  17. var returnValue = handler.onResolved(value);
  18. handler.resolve(returnValue);
  19. }
  20. this.then = function (onResolved) {
  21. return new Promise(function (resolve) {
  22. handle({
  23. onResolved: onResolved,
  24. resolve: resolve,
  25. });
  26. });
  27. };
  28. fn(resolve);
  29. }
  30. function doSomething() {
  31. return new Promise(function (resolve) {
  32. resolve(666);
  33. });
  34. }
  35. function doSomethingElse(value) {
  36. return new Promise(function (resolve) {
  37. resolve("did something else with " + value);
  38. });
  39. }
  40. var p = doSomething()
  41. .then()
  42. .then((data) => {
  43. console.log("Got a value: " + data);
  44. return doSomethingElse(data);
  45. })
  46. .then((value) => {
  47. console.log("Got anotherPromise: " + value);
  48. });

:::info rejected 状态实现 :::

function Promise(fn) {
  var state = "pending";
  var value;

  function resolve(newValue) {
    if (newValue && typeof newValue.then === "function") {
      newValue.then(resolve);
      return;
    }

    value = newValue;
    state = "resolved";
  }

  function reject(reason) {
    value = reason;
    state = "rejected";
  }

  function handle(handler) {
    var handlerCallback;

    if (state === "resolved") {
      handlerCallback = handler.onResolved;
    } else {
      handlerCallback = handler.onRejected;
    }

    if (!handlerCallback) {
      if (state === "resolved") {
        handler.resolve(value);
      } else {
        handler.reject(value);
      }
      return;
    }

    var returnValue = handlerCallback(value);
    handler.resolve(returnValue);
  }

  this.then = function (onResolved, onRejected) {
    return new Promise(function (resolve, reject) {
      handle({
        onResolved: onResolved,
        onRejected: onRejected,
        resolve: resolve,
        reject: reject,
      });
    });
  };

  fn(resolve, reject);
}

function somehowGetThevalue() {
  return Math.random() > 0.5 ? { value: ">0.5" } : { error: "<=0.5" };
}

function doSomething() {
  return new Promise(function (resolve, reject) {
    var result = somehowGetThevalue();

    if (result.error) {
      reject(result.error);
    } else {
      resolve(result.value);
    }
  });
}

var p = doSomething().then(
  (value) => {
    console.log("Success!", value);
  },
  (error) => {
    console.log("Fail!", error);
  }
);

:::info resolve 时捕捉异常也用 reject 处理 :::

function Promise(fn) {
  var state = "pending";
  var value;

  function resolve(newValue) {
    try {
      if (newValue && typeof newValue.then === "function") {
        newValue.then(resolve);
        return;
      }

      value = newValue;
      state = "resolved";
    } catch (e) {
      reject(e);
    }
  }

  function reject(reason) {
    value = reason;
    state = "rejected";
  }

  function handle(handler) {
    var handlerCallback;

    if (state === "resolved") {
      handlerCallback = handler.onResolved;
    } else {
      handlerCallback = handler.onRejected;
    }

    if (!handlerCallback) {
      if (state === "resolved") {
        handler.resolve(value);
      } else {
        handler.reject(value);
      }
      return;
    }

    var returnValue;
    try {
      returnValue = handlerCallback(value);
    } catch (e) {
      handler.reject(e);
      return;
    }
    handler.resolve(returnValue);
  }

  this.then = function (onResolved, onRejected) {
    return new Promise(function (resolve, reject) {
      handle({
        onResolved: onResolved,
        onRejected: onRejected,
        resolve: resolve,
        reject: reject,
      });
    });
  };

  fn(resolve, reject);
}

function somehowGetThevalue() {
  return Math.random() > 0.5 ? { value: ">0.5" } : { error: "<=0.5" };
}

function doSomething() {
  return new Promise(function (resolve, reject) {
    var result = somehowGetThevalue();

    if (result.error) {
      reject(result.error);
    } else {
      resolve(result.value);
    }
  });
}

var p = doSomething().then(
  (value) => {
    console.log("Success!", value);
  },
  (error) => {
    console.log("Fail!", error);
  }
);

:::info 使 promise 的 then 是异步的过程 :::

function Promise(fn) {
  var state = "pending";
  var value;

  function resolve(newValue) {
    try {
      if (newValue && typeof newValue.then === "function") {
        newValue.then(resolve);
        return;
      }

      value = newValue;
      state = "resolved";
    } catch (e) {
      reject(e);
    }
  }

  function reject(reason) {
    value = reason;
    state = "rejected";
  }

  function handle(handler) {
    setTimeout(function () {
      var handlerCallback;

      if (state === "resolved") {
        handlerCallback = handler.onResolved;
      } else {
        handlerCallback = handler.onRejected;
      }

      if (!handlerCallback) {
        if (state === "resolved") {
          handler.resolve(value);
        } else {
          handler.reject(value);
        }
        return;
      }

      var returnValue;
      try {
        returnValue = handlerCallback(value);
      } catch (e) {
        handler.reject(e);
        return;
      }
      handler.resolve(returnValue);
    }, 1);
  }

  this.then = function (onResolved, onRejected) {
    return new Promise(function (resolve, reject) {
      handle({
        onResolved: onResolved,
        onRejected: onRejected,
        resolve: resolve,
        reject: reject,
      });
    });
  };

  fn(resolve, reject);
}

function somehowGetThevalue() {
  return Math.random() > 0.5 ? { value: ">0.5" } : { error: "<=0.5" };
}

function doSomething() {
  return new Promise(function (resolve, reject) {
    var result = somehowGetThevalue();

    if (result.error) {
      reject(result.error);
    } else {
      resolve(result.value);
    }
  });
}

console.log(1);
var p = doSomething().then(
  (value) => {
    console.log("Success!", value);
  },
  (error) => {
    console.log("Fail!", error);
  }
);
console.log(2);