uni-app在finally块中调用uni.hideLoading()会导致catch语句中的提示语句未显示就关闭

发布于 1周前 作者 htzhanglong 来自 Uni-App

uni-app在finally块中调用uni.hideLoading()会导致catch语句中的提示语句未显示就关闭

示例代码:

uni.showLoading({
title: '正在加载',
})
try {
const {message} = await getXx()
} catch (e) {
uni.showLoading({
title: '加载出错',
})
} finally {
uni.hideLoading();
}

操作步骤:

在js 异常处理块中try和catch 分别调用showLoading显示对应的消息加载提示,然后在finally 中关闭加载提示,在真机uni.hideLoading();的表现与微信开发者工具中表现的不一致

预期结果:

在微信开发者工具模拟器中与预期的效果一致,发起请求失败会分别提示正在加载-加载出错-然后关闭Loading

实际结果:

在真机中,会只显示正在加载然后Loading就关闭了,catch中的Loading函数未来得及加载或者说加载出来的瞬间就被关闭了



| 信息类别         | 详细信息                   |
|------------------|----------------------------|
| 产品分类         | uniapp/小程序/微信          |
| PC开发环境操作系统 | Windows                    |
| PC开发环境操作系统版本号 | windows 10 专业版 20H2     |
| HBuilderX类型    | 正式                       |
| HBuilderX版本号  | 4.31                       |
| 第三方开发者工具版本号 | stable 1.06                |
| 基础库版本号      | x                         |
| 项目创建方式      | HBuilderX                  |

5 回复

这个问题不管是在真机还是模拟器中的表现,都能说的过去,但问题就在于效果不统一,我更偏向于模拟器中的效果,这样代码的阅读性会大大提高


应该是catch的时候紧接着就执行了finally了,如果想要一致性可以在finally里面增加个定时器来试试。也可以打印一下执行的耗时看看模拟器和真机上的时间差距有多大,最好是以真机为准。并且try catch也不是uniapp能控制的

增加定时器可以解决这个问题,但这种解决方式我个人感觉不管是从代码量还是阅读性的角度来说都不好,我觉得uni官方可以考虑在uni.hideToast/Loading();函数中新增可以传递自定义延迟的参数,这样对开发者来说少了很多麻烦事

回复 2***@qq.com: 你可以自行二次封装一下这个函数自行实现,你就只需要调用你封装的

在uni-app开发中,通常会在进行异步请求时显示一个加载提示,以改善用户体验。然而,如果在finally块中调用uni.hideLoading(),确实可能会导致在catch语句中的错误提示信息还未来得及显示就被关闭的问题。这是因为finally块中的代码无论请求成功还是失败都会执行,这就包括了隐藏加载提示的逻辑。

为了解决这个问题,可以调整代码结构,确保在显示错误信息之后再隐藏加载提示。以下是一个示例代码,展示了如何在处理异步请求时正确管理加载提示和错误信息的显示:

// 假设我们有一个异步请求函数 fetchData
async function fetchData() {
    try {
        // 显示加载提示
        uni.showLoading({ title: '加载中...' });

        // 模拟异步请求
        const response = await uni.request({
            url: 'https://example.com/api/data',
            method: 'GET'
        });

        // 请求成功处理
        console.log('请求成功:', response.data);

    } catch (error) {
        // 请求失败处理
        console.error('请求失败:', error);

        // 显示错误信息(这里可以根据需求调整显示方式)
        uni.showToast({
            title: '请求失败,请稍后再试',
            icon: 'none',
            duration: 3000
        });

    } finally {
        // 在finally块中,我们需要确保错误信息已经显示后再隐藏加载提示
        // 为了实现这一点,可以在catch中设置一个标志,然后在finally中检查这个标志
        // 但由于finally会无条件执行,更好的做法是将隐藏加载提示的逻辑放在catch之后(如果不需要在成功路径也隐藏)
        // 或者,使用setTimeout来稍作延迟,但这不是最佳实践,因为它引入了不确定的等待时间
        // 这里我们采用一个更优雅的解决方案:不在finally中隐藏加载提示,而是根据try/catch的结果来控制
    }

    // 隐藏加载提示(这里放在了try/catch之外,但仅在try成功执行完毕后隐藏,需要调整逻辑)
    // 为了确保在catch后也能隐藏,我们可以将隐藏逻辑封装成一个函数,并在适当的位置调用
    function hideLoadingIfNeeded() {
        // 由于我们希望在catch显示错误后也隐藏加载,因此这里不直接在finally中调用
        // 而是根据业务逻辑在适当位置调用,比如在这里(假设我们希望在所有路径结束后都隐藏)
        // 但注意,这样可能会导致在没有错误时也立即隐藏,如果需要在错误显示一段时间后隐藏,需要额外逻辑
        uni.hideLoading();
    }

    // 调用隐藏函数(根据实际需求调整调用位置)
    hideLoadingIfNeeded();
}

// 调用函数
fetchData();

注意,上述代码示例中的hideLoadingIfNeeded函数被放在了try/catch结构之外,并直接在函数末尾调用。这实际上并不是最佳实践,因为它没有考虑到在显示错误信息后给予用户足够的时间阅读。在实际应用中,你可能需要根据具体的业务逻辑来调整uni.hideLoading()的调用位置,以确保用户体验。

回到顶部