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

使用Expo AV在React Native中播放音频5秒后停止报错,求原因

问题原因及解决方案

报错原因

你在onPress回调里调用await playSound()后,立刻通过setTimeout去执行sound.stopAsync(),但React的setSound是异步状态更新方法——组件的sound状态并不会在playSound执行完毕后立刻更新。当5秒后setTimeout触发时,组件的sound变量还是初始的undefined,自然会抛出“找不到stopAsync方法”的错误。

修复方案

方案一:让playSound返回实例,直接在onPress里使用

不用依赖组件状态,直接获取创建的sound实例进行操作:

const [sound, setSound] = React.useState();

async function playSound() {
  console.log("Loading Sound");
  const { sound } = await Audio.Sound.createAsync(
    require("./assets/sound.mp3")
  );
  setSound(sound);

  console.log("Playing Sound");
  await sound.playAsync();
  return sound; // 返回创建的sound实例
}

React.useEffect(() => {
  return sound
    ? () => {
        console.log("Unloading Sound");
        sound.unloadAsync();
      }
    : undefined;
}, [sound]); 

// ...
<Button
  title="Play"
  onPress={async () => {
    const soundInstance = await playSound(); // 接收返回的实例

    setTimeout(async () => {
      await soundInstance.stopAsync(); // 直接用实例调用停止方法
    }, 5000);
  }}
/>

方案二:把定时逻辑放到playSound内部

直接在创建sound实例的函数里处理定时停止,避免依赖组件状态:

const [sound, setSound] = React.useState();

async function playSound() {
  console.log("Loading Sound");
  const { sound } = await Audio.Sound.createAsync(
    require("./assets/sound.mp3")
  );
  setSound(sound);

  console.log("Playing Sound");
  await sound.playAsync();
  
  // 直接在内部设置定时停止
  setTimeout(async () => {
    await sound.stopAsync();
  }, 5000);
}

React.useEffect(() => {
  return sound
    ? () => {
        console.log("Unloading Sound");
        sound.unloadAsync();
      }
    : undefined;
}, [sound]); 

// ...
<Button
  title="Play"
  onPress={playSound}
/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 21:01:52