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 中出现运行时错误