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

Expo MediaLibrary未处理Promise拒绝:无法获取相册列表

解决Expo MediaLibrary.getAlbumsAsync()的Promise拒绝错误问题

我看了你的代码和遇到的错误,问题主要出在async/await和.then/.catch的混用,以及权限判断后的逻辑分支处理不当,这确实是导致Promise拒绝错误和无法获取相册信息的核心原因,咱们一步步来修复:

问题分析

  1. 权限校验逻辑漏洞:你在获取权限后,只在status !== 'granted'时做了提示,但没有在权限通过的分支里才执行相册获取操作——也就是说,哪怕用户没给权限,代码还是会去调用MediaLibrary.getAlbumsAsync(),这必然会触发权限相关的Promise拒绝。
  2. async/await与.then的错误混用:你用了await来等待getAlbumsAsync(),但又链式调用了.then(),而且.then()里没有返回值,导致albumList最终是undefined。更关键的是,这种混用会让await无法正确捕获方法抛出的错误,而你的.catch()只能捕获.then()链里的异常,漏掉了getAlbumsAsync()本身的错误。

修正后的代码

import React from 'react';
import { ActivityIndicator, Button, Clipboard, Image, Share, StatusBar, StyleSheet, Text, TouchableOpacity, View, Alert, } from 'react-native';
import Expo, { MediaLibrary, Permissions, Constants, ImagePicker, registerRootComponent } from 'expo';

export default class ChoosePhotos extends React.Component {
  state = {
    image: null,
    uploading: false,
    cameraRollPerm: true, // 初始设为true,权限拒绝后再改为false
    albumList: [] // 新增状态存储相册列表
  };

  //Get Permission and get Albums list
  async componentDidMount(){
    await this.getAlbum(); // 加await确保组件挂载时完成权限和相册获取
  }

  getAlbum = async () => {
    try {
      const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
      if(status !== 'granted'){
        this.setState({ cameraRollPerm: false });
        Alert.alert(
          '',
          'Please grant permissions to access your media library to continue.',
          [
            {text: 'OK', onPress: () => console.log('OK Pressed')},
          ],
          { cancelable: false }
        );
        return; // 权限拒绝时直接返回,不执行后续相册获取逻辑
      }

      // 权限通过后才获取相册
      const albumArray = await MediaLibrary.getAlbumsAsync();
      console.log('获取到的相册列表:', albumArray);
      this.setState({ albumList: albumArray }); // 把相册列表存到状态里
    } catch (error) {
      console.log("获取相册失败:", error);
      Alert.alert('错误', '无法获取你的相册,请检查权限后重试');
    }
  }

  render() {
    console.log(this.state.image)
    let { image, albumList } = this.state;
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Text style={{ fontSize: 20, marginBottom: 20, textAlign: 'center', marginHorizontal: 15, }}>
          Example: Upload ImagePicker result
        </Text>
        {/* 可在这里添加相册列表展示 */}
        {albumList.length > 0 && (
          <View style={{marginVertical:20}}>
            <Text>你的相册:</Text>
            {albumList.map(album => (
              <Text key={album.id}>{album.title}</Text>
            ))}
          </View>
        )}
        <Button onPress={this._pickImage} title="Pick an image from camera roll" />
        <Button onPress={this._takePhoto} title="Take a photo" />
        <StatusBar barStyle="default" />
      </View>
    );
  }

  _takePhoto = async () => {
    let pickerResult = await ImagePicker.launchCameraAsync({ });
    this.props.navigation.navigate('SizeSelectionScreen', {imageLink: pickerResult.uri});
  };

  _pickImage = async () => {
    let pickerResult = await ImagePicker.launchImageLibraryAsync({ });
    this.props.navigation.navigate('SizeSelectionScreen', {imageLink: pickerResult.uri});
  };
}

关键修改点

  • 用try/catch包裹整个异步逻辑,统一捕获权限请求和相册获取过程中的所有错误,避免Promise拒绝未被处理的问题。
  • 权限拒绝时添加return,终止后续代码执行,防止无权限时调用相册接口。
  • 去掉冗余的.then(),改用纯async/await写法,让代码更清晰,同时确保能正确获取相册数组并存储到组件状态中。
  • 新增albumList状态来存储相册数据,方便在render里展示。

这样调整后,你应该就能正常获取相册列表,也不会再出现Promise拒绝的错误了。

内容的提问来源于stack exchange,提问作者Abrar A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:44:15