从头开始创建的自定义 JavaScript Promise 中的“然后”会在 Promise

我正在尝试从头开始创建一个简单的自定义承诺。


由于某种原因,在调用then之前正在执行。onResolve function因此,该response变量是一个空字符串。我这里哪里出错了?


索引.js


import CustomPromise from "./customPromise";

const makeApiCall = () => {

  return new CustomPromise((success, failure) => {

    setTimeout(() => {

      let apiResponse = { statusCode: 200, response: "hello" };

      if (apiResponse.statusCode == 200) {

        success(apiResponse);

      } else {

        failure(apiResponse);

      }

    }, 1000);

  });

};

makeApiCall().then(response => {

  console.log(response);

});


CustomPromise.js


export default class CustomPromise {

  constructor(executorFunc) {

    this.onResolve = this.onResolve.bind(this);

    this.onReject = this.onReject.bind(this);

    this.response = "";

    executorFunc(this.onResolve, this.onReject);

  }

  then(input) {

    input(this.response);

  }

  onResolve(response) {

    this.response = response;

  }


  onReject(input) {

    input();

  }

}


缥缈止盈
浏览 90回答 1
1回答

SMILET

当调用时,CustomPromise.then您可以看到您只是在继续input并立即调用它,而不管承诺的状态如何。我认为您想要做的是创建一个task queue,并在解决后,您将继续执行它。您还错过了一些关键的事情。首先,您需要维护一个state内部的 Promise,以便您知道 Promise 何时发生settled。这使得您无法多次解决/拒绝承诺。您的reject函数可能不应该只是执行输入。您通常将 a 传递reason给拒绝,然后它将执行所有catch任务。没有链接支持。不确定这是否是你的目标。const functionOrNoop = (fn) => {  let result = () => {};  if (typeof fn === "function") {    result = fn;  }  return result;};class CustomPromise {  constructor(executor) {    this.queue = [];    this.state = "pending";    this.value = null;    this.reason = null;    executor(this.onResolve, this.onReject);  }  static reject(reason) {    return new CustomPromise((_, reject) => reject(reason));  }  static resolve(value) {    return new CustomPromise((resolve) => resolve(value));  }  then(fn) {    return new CustomPromise((resolve, reject) => {      const resolved = (value) => {        try {          resolve(fn(value))        } catch (e) {          reject(e);        }      };      this.enqueue({        resolved,        rejected: reject      });    });  }  catch (fn) {    return new CustomPromise((resolve, reject) => {      const rejected = (reason) => {        try {          resolve(fn(reason))        } catch (e) {          reject(e);        }      };      this.enqueue({        rejected      });    });  }  onResolve = (value) => {    if (this.state === "pending") {      this.state = "resolved";      this.value = value;      this.finalize();    }  }  onReject = (reason) => {    if (this.state === "pending") {      this.state = "rejected";      this.reason = reason;      this.finalize();    }  };  enqueue(task) {    if (this.state === "pending") {      this.queue.push(task);    } else {      this.eval(task);    }  }  eval(task) {    if (this.state === "resolved") {      functionOrNoop(task.resolved)(this.value);    } else if (this.state === "rejected") {      functionOrNoop(task.rejected)(this.reason);    }  }  finalize() {    this.queue.forEach((task) => this.eval(task));    this.queue = [];  }}const p = CustomPromise.resolve("hello")p  .then((value) => value.toUpperCase())  .then((value) => `J${value.slice(1)}`)  .then((value) => console.log(value))p.then((value) => console.log(value));p  .then(() => {    throw new Error(":(")  })  .catch((e) => console.log(e.message))  .then(() => {    throw new Error(":)")  })  .then(() => console.log("SHOULD NOT CALL!"))  .catch((e) => console.log(e.message));这是一个示例(所以预计会有错误),但它封装了我上面提到的一些内容。Promise 确实很复杂,您会错过诸如“微任务”之类的东西以及数万小时的测试、开发和审查。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript