【问题标题】:Async-await not working as I expected in forEach loop异步等待在 forEach 循环中没有按预期工作
【发布时间】:2022-01-06 13:14:50
【问题描述】:

我正在使用 WebRTC 尝试将两个用户连接在一起。我调用 createOffer,然后使用 createOffer 返回的内容设置对等连接的本地描述。我不知道为什么会出现以下错误:

注意:我使用 firebase firestore 作为信号服务器

Uncaught (in promise) DOMException: Cannot set local offer when 尚未调用 createOffer。

这是我的代码:

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

  users.forEach(async (doc) => {
    if (isNotAlreadyConnected(doc.id)) {
      newPeerConnection = new UserConnection(servers, doc.id);

      if (doc.id != sessionStorage.getItem("userID") && doc.id != "metadata") {

        let connOfferDescription =
          await newPeerConnection.userPeerConnection.createOffer();

        await newPeerConnection.userPeerConnection.setLocalDescription(
          connOfferDescription
        );

        await doc.collection("offer-candidates").doc("offer").set({
          offer: newPeerConnection.userPeerConnection.localDescription,
        });
      }

      peerConnections.push(newPeerConnection);
    }
  });
}

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

  getRemoteUserID() {
    return this.remoteUserID;
  }
}

【问题讨论】:

  • 您似乎混淆了应用程序的异步部分。例如,当方法没有返回值时,像 await newPeerConnection 这样的调用是一个警告标志。
  • @RandyCasburn 但我没有使用这些方法,我仍然遇到同样的问题。

标签: javascript foreach async-await


【解决方案1】:

我在这里有点盲目,但在 forEach(或 map、filter、reduce 等)中使用 async-await 是一个常见的问题。它本质上只是触发了一堆异步调用。

在触发下一个回调之前,它不会等待该回调中发生的事情完成。 forEach 的内部需要等待回调并且回调必须返回一个承诺。

因为您在循环之外有let newPeerConnection,所以您可能在任何createOffer 调用完成之前多次写入该变量。

如果这些同时调用都不会相互影响,您可以将该变量带入循环中。否则,如果您想逐个运行它们,只需使用 for-of 循​​环。这可能看起来像这样:

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

    for (let doc of users) {
        if (!isNotAlreadyConnected(doc.id)) continue;

        newPeerConnection = new UserConnection(servers, doc.id);

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

            await newPeerConnection.userPeerConnection.setLocalDescription(
                connOfferDescription
            );

            await doc.collection('offer-candidates').doc('offer').set({
                offer: newPeerConnection.userPeerConnection.localDescription,
            });
        }

        peerConnections.push(newPeerConnection);
    }
}

为了更好的做法,请注意其中的几个小改动:!== 而不是 !=,并检查 bool 的逆并尽早继续以避免厄运金字塔。

【讨论】:

    猜你喜欢
    • 2018-05-05
    • 2015-05-06
    • 2019-04-19
    • 2021-03-27
    • 2020-03-04
    • 2019-04-07
    • 2023-03-03
    • 2022-01-22
    • 2018-12-02
    相关资源
    最近更新 更多