TIL 029計画の直接実施


前文は、非同期apiを順次送信することを考慮したことがある.javascriptでこれを簡単に実現する方法はプログラミングです.
この文章では、キャリアを直接体現し、キャリアを理解しようとします.

1.同期フィルタ処理


まず同期処理を実施しましょう.まずテストコードの動作を想像し、promisのpressolveはすぐに実行され、「first」、「second」、「third」を受信して使用されます.
console.time("동기처리");
new MyPromise((res, rej) => res("first"))
  .then(msg => {
    console.log(msg);
    return "second";
  })
  .then(msg => {
    console.log(msg);
    return "third";
  })
  .then(msg => {
    console.log(msg);
    console.timeEnd("동기처리");
  });
MyPromiseを宣言します.現在の状態(pending、resolved、recjected)の状態を表します.Promisが解析され、拒否されたときの値と、次のPromiseを含むチェーンが含まれます.
class MyPromise {
  constructor(callback) {
    this.state = "pending";
    this.value = undefined;
    this.chain = undefined;
    callback(this.resolve.bind(this), this.reject.bind(this));
  }
解析後、valueとstateが変更され、次のプロセスチェーンがある場合は実行されます.
断られたとき、私も先に同意させます.
  resolve(value) {
    this.value = value;
    this.state = "resolved";
    this.chain?.();
  }

  reject(value) {
    this.value = value;
    this.state = "rejected";
    this.chain?.();
  }
その時、実はプロミスも返却されます.このときthenの関数をresolutionに入れ,そのresolution関数を前のpromisのchainに入れる.つまり、前のフロミスが解決されました.chainが実行され、promisのresolution実行時に加わったコールバック関数が連続して実行されます.トリガを前に置いておきましょう.
現在のテスト例のように同期している場合は、chainに入って解決するのを待つ必要はなく、新しいpromisをすぐに解決すればよい.
  then(callback) {
    if (this.state === "pending") {
      return new MyPromise(resolve => (this.chain = () => resolve(callback(this.value))));
    }
    if (this.state === "resolved") {
      return new MyPromise(resolve => resolve(callback(this.value)));
    }
    return this;
  }
}

2.非同期フィルタ処理


非同期タスクプロセスであればどうなりますか?前の記事のようにapiの応答を連続的に使用する必要がある場合は?
console.time("비동기처리");
new MyPromise((res, rej) => setTimeout(() => res("first"), 1000))
  .then(msg => {
    console.log(msg);
    return new MyPromise((res, rej) => setTimeout(() => res("second"), 1000));
  })
  .then(msg => {
    console.log(msg);
    return new MyPromise((res, rej) => setTimeout(() => res("third"), 1000));
  })
  .then(msg => {
    console.log(msg);
    console.timeEnd("비동기처리");
  });
この値を返すのではなく、新しいプロセスを返します.これに対して例外処理を行う必要がある.
resolve関数セクションが変更され、値がpromisの場合、promisが解析された場合にのみ解析または(promis)されます.つまり、心の中で待っていたフロミスの返事.
 resolve(value) {
    if (value instanceof MyPromise) {
      value.then(innerPromiseValue => this.setThisPromiseValue(innerPromiseValue));
    } else {
      this.setThisPromiseValue(value);
    }
  }

  setThisPromiseValue(value) {
    this.value = value;
    this.state = "resolved";
    this.chain?.();
  }
すべてのPromisの回答を待って、順番に実行して、3秒かかりました.

3.catchによる異常処理


非同期タスクの例外を処理するのは容易ではありませんが、実際のプロセスは.catchメソッドはエラー処理を行うことができます.
テストコードから見ると、2番目のプロセスはエラーをregに返し、3番目のプロセスは実行せずcatchに戻ります.
console.time("에러처리");
new MyPromise((res, rej) => setTimeout(() => res("first"), 1000))
  .then(msg => {
    console.log(msg);
    return new MyPromise((res, rej) => setTimeout(() => rej("에러"), 1000));
  })
  .then(msg => {
    console.log(msg);
    return new MyPromise((res, rej) => setTimeout(() => res("third"), 1000));
  })
  .then(msg => {
    console.log(msg);
    return msg;
  })
  .catch(err => {
    console.log(err);
    console.timeEnd("에러처리");
  });
catchのコールバック関数はchainではなくErrorHandlerによって保存されます.
実際にはpromiseが解析されたのか拒否されたのか分からないため,すべてのチェーンを接続する必要がある.また,非同期処理ではtry catchがエラーで検出され拒否が実行される.
class MyPromise {
  constructor(callback) {
    this.state = "pending";
    this.value = undefined;
    this.chain = undefined;
    this.errorHandler = undefined;
    try {
      callback(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error);
    }
  }
もしvalueがpromisであれば、このinner promisの間違いもcatchして私(promis)を学校に帰らせるべきだ.
  resolve(value) {
    if (value instanceof MyPromise) {
      value
        .then(innerPromiseValue => this.setThisPromiseValue(innerPromiseValue))
        .catch(innerPromiseValue => this.reject(innerPromiseValue));
    } else {
      this.setThisPromiseValue(value);
    }
  }

  setThisPromiseValue(value) {
    this.value = value;
    this.state = "resolved";
    this.chain?.();
  }
拒否するとerrorhandlerが実行されます.
  reject(value) {
    this.value = value;
    this.state = "rejected";
    this.errorHandler?.();
  }
そして実行時に、前のfromisチェーンで、私のfromisの決議にコールバックを置きます.前のプロセスで拒否が発生し、chainではなくErrorHandlerが実行された場合、コールバックは実行されず、拒否を渡すだけです.
したがって、erroHandlerはthenコールバックを実行せず、値の伝達を拒否するだけです.
  then(callback) {
    if (this.state === "pending") {
      return new MyPromise((resolve, reject) => {
        this.chain = () => resolve(callback(this.value));
        this.errorHandler = () => reject(this.value);
      });
    }
    if (this.state === "resolved") {
      return new MyPromise(resolve => resolve(callback(this.value)));
    }
    return this;
  }
.catch実行時は逆です.chainはresolveのみを実行して値を渡します(前に拒否されていないため、値のみを渡します).ErrorHandlerはcatchコールバックも実行します.したがって、前に渡された拒否がある場合はcatchが実行されます.
  catch(callback) {
    if (this.state === "pending") {
      return new MyPromise((resolve, reject) => {
        this.chain = () => resolve(this.value);
        this.errorHandler = () => reject(callback(this.value));
      });
    }
    if (this.state === "reject") {
      return new MyPromise((resolve, reject) => reject(callback(this.value)));
    }
    return this;
  }
}
3つ目のプロセスは、実行せずにスキップする様子です.

完全なコード


そのため、自分のプロ選手は一定の役割を果たすことができます.そしてcatch間はpromisの決意で結びつき,価値的にもpromisを利用できる点が核心である.
class MyPromise {
  constructor(callback) {
    this.state = "pending";
    this.value = undefined;
    this.chain = undefined;
    this.errorHandler = undefined;
    try {
      callback(this.resolve.bind(this), this.reject.bind(this));
    } catch (error) {
      this.reject(error);
    }
  }

  resolve(value) {
    if (value instanceof MyPromise) {
      value
        .then(innerPromiseValue => this.setThisPromiseValue(innerPromiseValue))
        .catch(innerPromiseValue => this.reject(innerPromiseValue));
    } else {
      this.setThisPromiseValue(value);
    }
  }

  setThisPromiseValue(value) {
    this.value = value;
    this.state = "resolved";
    this.chain?.();
  }

  reject(value) {
    this.value = value;
    this.state = "rejected";
    this.errorHandler?.();
  }

  then(callback) {
    if (this.state === "pending") {
      return new MyPromise((resolve, reject) => {
        this.chain = () => resolve(callback(this.value));
        this.errorHandler = () => reject(this.value);
      });
    }
    if (this.state === "resolved") {
      return new MyPromise(resolve => resolve(callback(this.value)));
    }
    return this;
  }

  catch(callback) {
    if (this.state === "pending") {
      return new MyPromise((resolve, reject) => {
        this.chain = () => resolve(this.value);
        this.errorHandler = () => reject(callback(this.value));
      });
    }
    if (this.state === "reject") {
      return new MyPromise((resolve, reject) => reject(callback(this.value)));
    }
    return this;
  }
}

追加するセクション


最後にメソッドも追加します.コンストラクション関数にfinallyのresolutionとcallbackを追加し、状況に応じて(最後のプロセスで)実行すればいいです.
また、エラーが発生して拒否されたが、そのエラーを処理していないcatchの場合、エラーを引き起こすために除外処理を追加する必要がある場合があります.
機会があればまた実現します