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

WebRTC场景下forEach循环中Async-await未按预期运行 调用createOffer后报错

问题根因

  • 你使用的Array.prototype.forEach不支持等待异步回调,所有循环内的异步逻辑会并发执行,无法按你预期的顺序执行
  • 你在循环外部声明了newPeerConnection变量,每次循环都会覆盖这个变量的引用,等到createOffer等异步操作真正执行时,拿到的可能是后续循环创建的其他PeerConnection实例,导致操作的实例和调用createOffer的实例不匹配,就会抛出「未调用createOffer就设置本地offer」的错误

修复方案

把forEach循环替换为支持异步等待的for...of循环,同时把newPeerConnection的声明放到循环内部,避免变量被覆盖,可额外添加错误捕获逻辑方便排查问题。
修复后的代码如下:

async function preformSignaling() {
  let users = await negDoc.collection("users").get();

  // 替换forEach为for...of,支持异步等待
  for (const doc of users.docs) {
    if (isNotAlreadyConnected(doc.id)) {
      // 变量声明放到循环内部,每次循环生成独立引用,不会被覆盖
      const newPeerConnection = new UserConnection(servers, doc.id);

      if (doc.id != sessionStorage.getItem("userID") && doc.id != "metadata") {
        try {
          let connOfferDescription =
            await newPeerConnection.userPeerConnection.createOffer();

          await newPeerConnection.userPeerConnection.setLocalDescription(
            connOfferDescription
          );

          await doc.collection("offer-candidates").doc("offer").set({
            offer: newPeerConnection.userPeerConnection.localDescription,
          });
        } catch (err) {
          // 可自定义错误处理逻辑
          console.error("信令流程执行失败", err);
        }
      }

      peerConnections.push(newPeerConnection);
    }
  }
}

class UserConnection {
  constructor(servers, remoteUserID) {
    this.userPeerConnection = new RTCPeerConnection(servers);
    this.remoteStream = new MediaStream();
    this.remoteUserID = remoteUserID;
  }

  getRemoteUserID() {
    return this.remoteUserID;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:36:10