【问题标题】:Code inside async function ignores await property异步函数内的代码忽略等待属性
【发布时间】:2021-05-26 16:57:43
【问题描述】:

我的问题在于执行顺序:在 wait() 函数内部调用的 connectToNewUser 函数在 myPeer.on(' call'),也在里面。我将我的代码放入 async\await 函数中,但没有结果,以某种方式首先执行 "user-connected"。如果我向 connectToNewUser

添加超时
socket.on('user-connected', userId => {
    setTimeout(connectToNewUser,1000,userId,stream)
  })

,它开始按我的需要工作,但我想用 await 解决它。哪里出了问题?

 const socket = io("/");
const videoGrid = document.getElementById("video-grid");
const myPeer = new Peer(undefined, {
    host: "/",
    port: "3001"
});

const myVideo = document.createElement('video');
myVideo.muted = true;
const peers = {};

navigator.mediaDevices.getUserMedia({
    video: true,
    audio: true
}).then(stream => {
    addVideoStream(myVideo, stream);

    wait(myPeer, stream);
});

socket.on("user-disconnected", userId => {
    peers[userId] && peers[userId].close();
});

myPeer.on("open", id => {
    socket.emit("join-room", ROOM_ID, id);
})

const connectToNewUser = (userId, stream) => {
    const call = myPeer.call(userId, stream);
    const video = document.createElement('video');
    
    call.on("stream", userVideoStream => {
        addVideoStream(video, userVideoStream);
    });

    call.on("close", () => {
        video.remove();
    });

    peers[userId] = call
}

const addVideoStream = (video, stream) => {
    video.srcObject = stream;
    video.addEventListener('loadedmetadata', () => {
        video.play();
    })

    videoGrid.append(video);
} 

async function wait(myPeer, stream) {
    await myPeer.on("call", call => {
        call.answer(stream);

        const video = document.createElement("video");

        call.on("stream", userVideoStream => {
            addVideoStream(video, userVideoStream)
        })
    });

    await socket.on("user-connected", userId => {
        connectToNewUser(userId, stream);
    });
}

【问题讨论】:

  • 这是javascript吗?如果是这样,那么我会说这将是一个重要的添加标签。
  • 你需要用 Promise 包装 myPeer.on('call') 并在回调中解决它。
  • 不工作。举个例子好吗?

标签: javascript async-await


【解决方案1】:

await 是一个管理promises的工具。

await myPeer.on("call", 返回一个承诺,所以你不能有用地await 它。

await myPeer.on("call", 确实接受了回调,因此您可能能够wrap it in a promise但是……

Promises 是一种标准 API,用于处理异步一次发生的事情。

myPeer.on("call", 看起来就像每次你接到电话都会发生,这将使它不适合与 promises 一起使用。如果是这样,您应该继续使用它提供的回调 API(通过您可能想查看 RxJs,它尝试对重复事件执行 Promise 对非重复事件执行的操作)。

并非所有异步都适合与await 一起使用。

【讨论】:

  • 看起来你是对的)我可以使用 RxJs 调度程序修复它,但它比简单的超时功能要复杂得多。感谢您的回复!
【解决方案2】:

试试这个:

function waitCall(myPeer) {
  return new Promise((resolve) => {
    myPeer.on("call", call => {
      resolve(call)
    })
  })
}

function waitStream(myPeer){
  return new Promise((resolve) => {
    myPeer.on("stream", userVideoStream => {
      resolve(userVideoStream)
    })
  })
}

function waitUserConnected(myPeer){
  return new Promise((resolve) => {
    myPeer.on("user-connected", userId => {
      resolve(userId)
    })
  })
}

async function wait(myPeer, stream){
  const call = await waitCall(myPeer)
  call.answer(stream)
  
  const video = document.createElement("video")
  const userVideoStream = await waitStream(myPeer)
  addVideoStream(video, userVideoStream)

  const userId = await waitUserConnected(myPeer)
  connectToNewUser(userId, stream)
}

【讨论】:

    猜你喜欢
    • 2021-09-10
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多