android 应用程序可能出现未处理的 Promise Rejection

Posted

技术标签:

【中文标题】android 应用程序可能出现未处理的 Promise Rejection【英文标题】:Possible Unhandled Promise Rejection with an android application 【发布时间】:2022-01-01 15:25:33 【问题描述】:

过去几天我一直在练习 react native。我正在尝试制作电影页面应用程序。我的代码可以正常工作。但我的问题是它显示了一个关于可能未处理的承诺拒绝的错误。我知道问题出在哪里,但我不知道如何解决。

这是问题的根源(Details.js):

import  isEmptyStatement  from '@babel/types';
import React, useEffect, useState from 'react';
import Text from 'react-native';
import getMovie, getTv from '../services/services';

const Detail = (route, navigation) => 
    const movieId = route.params.movieDetail.id;

    const [movieDetail, setMovieDetail] = useState([]);
    const [movieTv, setMovieTv] = useState([]);
    
    const [loaded, setLoaded] = useState(false);
    const [success, setSuccess] = useState(false);

    useEffect(() => 
        getMovie(movieId).then(movieData => 
            if(movieData == null) 
                setLoaded(false);
            
            else 
                setMovieDetail(movieData);
                setLoaded(true);
            
        );
    , [movieId]);
    
    useEffect(() => 
        getTv(movieId).then(movieTv => 
            if(movieTv == null) 
                setLoaded(false);
            
            else 
                setMovieTv(movieTv);
                setLoaded(true);
            
        );
    , [movieId]);

    if(movieDetail.title == null)
        return (
            <React.Fragment>
                loaded && <Text>movieTv.name</Text>
            </React.Fragment>
        );
    
    else 
        return (
            <React.Fragment>
                loaded && <Text>movieDetail.title</Text>
            </React.Fragment>
        );
    

    console.log(movieTv.success);
    


export default Detail;

这是他们获取数据的地方(services.js):

import axios from 'axios';

const apiUrl = 'https://api.themoviedb.org/3';
const apiKey = 'api_key=31a7f8174b1e2c29744ec644af796973';

// Get Popular Movies
export const getPopularMovies = async () => 
    const resp = await axios.get(`$apiUrl/movie/popular?$apiKey`,);
    return resp.data.results;
;

// Get Upcoming Movies
export const getUpcomingMovies = async () => 
    const resp = await axios.get(`$apiUrl/movie/upcoming?$apiKey`,);
    return resp.data.results;
;

// Get Popular TV
export const getPopularTv = async () => 
    const resp = await axios.get(`$apiUrl/tv/popular?$apiKey`,);
    return resp.data.results;
;

export const getFamilyMovies = async () => 
    const resp = await axios.get(`$apiUrl/discover/movie?$apiKey&with_genres=10751`,);
    return resp.data.results;
;

export const getMovie = async id => 
    const resp = await axios.get(`$apiUrl/movie/$id?$apiKey`,);
    return resp.data;
;

export const getTv = async id => 
    const resp = await axios.get(`$apiUrl/tv/$id?$apiKey`,);
    return resp.data;
;

【问题讨论】:

【参考方案1】:

您已经使用了多个异步调用并在 Details.js 类中处理返回的承诺。但在每种情况下,您只通过提供 then 回调来处理成功(承诺解决)路径。

例如,考虑这个

getTv(movieId).then(movieTv => 
    if(movieTv == null) 
        setLoaded(false);
    
    else 
        setMovieTv(movieTv);
        setLoaded(true);
    
);

这里您的应用程序将运行良好,只要网络调用成功并且后端返回成功(例如 2xx)响应。但是如果发生任何错误,您的应用程序将会崩溃,因为您没有通过处理 promise 拒绝来处理错误。

所以你应该做的是为每个承诺添加一个catch 回调并优雅地处理错误场景。您可以执行诸如记录错误、设置任何标志以指示加载失败、在 UI 上显示错误等操作。

getTv(movieId).then(movieTv => 
    if(movieTv == null) 
        setLoaded(false);
    
    else 
        setMovieTv(movieTv);
        setLoaded(true);
    
).catch(err => 
  console.log(err);
  setLoaded(false);
);

【讨论】:

谢谢!由于捕获,该错误不再弹出。现在一切正常。

以上是关于android 应用程序可能出现未处理的 Promise Rejection的主要内容,如果未能解决你的问题,请参考以下文章

java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程内创建处理程序,在 android 中出现运行时错误

设置firebase时出错,可能会出现未处理的承诺拒绝

Android_程序未处理异常的捕获与处理

使用 useMutation 可能出现未处理的承诺拒绝警告

android服务如何对未处理的异常做出反应?

React Native 中可能出现未处理的 Promise Rejection 网络错误