You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中如何让save方法等待collection.create()完成后执行

解决Repository中save方法需等待集合创建完成的问题

Got it, the problem here is that your collection.create() call runs asynchronously in the constructor, but your save method might execute before that operation finishes—leading to crashes when trying to interact with a collection that isn't ready yet. Let's fix this properly with a couple of solid approaches:

方案一:子类内维护初始化Promise,确保save等待完成

We can add a ready Promise to your UserRepository that resolves once the collection is confirmed to exist (either created successfully or already present). All collection-dependent methods like save will await this Promise first:

class UserRepository extends BaseRepository<User> {
  private readonly ready: Promise<void>;

  constructor() {
    super();
    this.collection = this.db.collection('users');
    // Wrap collection creation logic into the ready Promise
    this.ready = this.ensureCollectionExists();
  }

  private async ensureCollectionExists(): Promise<void> {
    try {
      const res = await this.collection.create();
      if (res.code === 200) {
        console.log('Users collection created successfully');
      }
    } catch (err) {
      if (err.code === 409) {
        console.log('Users collection already exists, no action needed');
      } else {
        // Don't swallow unexpected errors—let them propagate so you can handle failures
        throw err;
      }
    }
  }

  // Override save to wait for collection readiness before proceeding
  async save(entity: User): Promise<void> {
    await this.ready;
    // Delegate to parent class's save logic
    await super.save(entity);
  }
}

class BaseRepository<T> {
  protected db: /* Your DB client type */;
  protected collection: /* Your collection type */;

  async save(entity: T): Promise<void> {
    // Example parent save logic—adjust to your actual implementation
    await this.collection.insertOne(entity);
  }
}

方案二:抽离初始化逻辑到BaseRepository(适合多Repository场景)

If you have multiple repositories that need this collection readiness check, move the logic up to the BaseRepository to avoid code duplication:

class BaseRepository<T> {
  protected db: /* Your DB client type */;
  protected collection: /* Your collection type */;
  private readonly ready: Promise<void>;

  constructor(collectionName: string) {
    this.db = /* Initialize your DB client here */;
    this.collection = this.db.collection(collectionName);
    this.ready = this.ensureCollectionExists();
  }

  private async ensureCollectionExists(): Promise<void> {
    try {
      const res = await this.collection.create();
      if (res.code === 200) {
        console.log(`Collection "${this.collection.name}" created successfully`);
      }
    } catch (err) {
      if (err.code === 409) {
        console.log(`Collection "${this.collection.name}" already exists`);
      } else {
        throw err;
      }
    }
  }

  // Base save method automatically waits for collection readiness
  async save(entity: T): Promise<void> {
    await this.ready;
    await this.collection.insertOne(entity);
  }
}

class UserRepository extends BaseRepository<User> {
  constructor() {
    // Pass collection name to parent constructor
    super('users');
  }
}

Why this works

  • The ready Promise acts as a gatekeeper: any method that needs to interact with the collection will wait until the collection is confirmed to exist.
  • Constructor can't be async, so wrapping the async initialization logic into a Promise is the cleanest way to handle this.
  • We don't swallow unexpected errors (like permission issues or DB connection failures)—this ensures you catch and handle real problems instead of letting the app crash silently later.

内容的提问来源于stack exchange,提问作者Almis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:36:13