Open4

【JavaScript/TypeScript】Promise Tips📝

まさぴょん🐱まさぴょん🐱

awaitせずに明示的に、Promiseを解決したい時📝

  // TODO: 専用のエンドポイントを呼ぶように修正する予定。
  const webinarEventApiCaller = async (_req: CloneEventReq) => {
    console.log("call webinar event clone api");
    return Promise.resolve();
  };
junerjuner

次のコードみたいに promise とは別に 値を管理すると await しなくても完了状態に移行できる手もありますね。

{
  const {status, now, resolve} = withStatusResolvers();
  resolve(2);
  status(); // => "completed"
  now(); // => 2
}
{
  const {status, now, resolve, promise} = withStatusResolvers();
  setTimeout(() => resolve(3));
  status(); // => "pending"
  now(); // => Error
  await promise; // wait .. => 3
  now(); // => 3
}

/**
 * @template T
 */
function withStatusResolvers() {
  const {
    promise,
    resolve: resolve_,
    reject: reject_,
  } = Promise.withResolvers();
  let status = undefined;
  /** @type {T} */
  let result = undefined;
  /** @type {never} */
  let reason = undefined;
  /**
   * @param {T} r 
   */
  function resolve(r) {
    if (status) return;
    status = "fulfilled";
    result = r;
    resolve_(r);
  }
  /**
   * @param {never} r 
   */
  function reject(r) {
    if (status) return;
    status = "rejected";
    reason = r;
    reject_(r);
  }
  return {
    status() {
      return status ? "completed" : "pending";
    },
    now() {
      if (status === "fulfilled") return result;
      if (status === "rejected") throw reason;
      throw new Error("Not completed yet");
    },
    promise,
    resolve,
    reject,
  };
}

https://github.com/tc39/proposal-import-sync/issues/7#issuecomment-2687259689

まさぴょん🐱まさぴょん🐱

promise とは別に 値を管理すると await しなくても完了状態に移行できる手

なるほどです👀✨
いつもナイスなコメントありがとございます🙏

Ecma TC39のIssueリンク確認します📝

junerjuner

issues で言われている通り、 通常の Promise だと then する時点で await null 相当 の キュー切り替えを実施する必要があり、それを崩すのは結構処理的にわっちゃになりがちなので この now() メソッドが通ることは無いですが、 続けないのであれば こんな感じに取得する方法は無いわけではない という実装なので注意は必要です。