uni-app 对uni.request自定义封装new Promise后,通过async、await方式调用,手机端uni.showLoading和uni.hideLoading方法报错

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

uni-app 对uni.request自定义封装new Promise后,通过async、await方式调用,手机端uni.showLoading和uni.hideLoading方法报错

产品分类

uniapp/小程序/微信

开发环境信息

项目 信息
PC开发环境操作系统 Windows
操作系统版本号 21H2
第三方开发者工具版本号 3.7.11.20230427
基础库版本号 3.0.0
项目创建方式 CLI
CLI版本号 3.0.0-alpha-3060720221018002

示例代码

export const api = (url: string, reqData: object) => {  
    return new Promise((resolve) => {  
        uni.showLoading({  
            title: "加载中"  
        })  
        uni.request({  
            url,  
            method: "POST",  
            data: reqData,  
            header: {  
                "from-source": "lowcode"  
            },  
            success: ({ data }) => {  
                if (data.code === "0") {  
                    resolve(data.data)  
                } else {  
                    resolve({ err: true })  
                }  
            },  
            fail: (res) => {  
                console.log(res);  
                resolve({ err: true })  
            },  
            complete: () => {  
                uni.hideLoading()  
            }  
        });  
    })  
}  

const data = await api('https://')

操作步骤

如上代码示例

预期结果

在真机端不会报错

实际结果

在真机端提示:errMsg":"hideLoading:fail:toast can't be found"

bug描述

代码如下:

export const api = (url: string, reqData: object) => {  
    return new Promise((resolve) => {  
        uni.showLoading({  
            title: "加载中"  
        })  
        uni.request({  
            url,  
            method: "POST",  
            data: reqData,  
            header: {  
                "from-source": "lowcode"  
            },  
            success: ({ data }) => {  
                if (data.code === "0") {  
                    resolve(data.data)  
                } else {  
                    resolve({ err: true })  
                }  
            },  
            fail: (res) => {  
                console.log(res);  
                resolve({ err: true })  
            },  
            complete: () => {  
                uni.hideLoading()  
            }  
        });  
    })  
}  

const data = await api('https://')

在ios11手机上报错:errMsg":"hideLoading:fail:toast can't be found,如果改成wx.showLoading和wx.hideLoading(),则不会报错


6 回复

这个和封装pomise有啥关系呢,你在其他场景试试有没有报错


这个就是微信的锅,在ios,uni.showLoading后马上执行hideLoading就会报这个错误,报就让随他吧,不影响其他逻辑。硬是要解决,就延时执行hideLoading

改成 wx.hideLoading() 就不报了 解决了后 想到是uni问题 才搜到的这个帖子

延时几百毫秒

await uni.showLoading

uni-app 中对 uni.request 进行自定义封装,并使用 Promise 以及 async/await 来处理请求是一种常见的做法。关于你提到的 uni.showLoadinguni.hideLoading 方法报错的问题,这通常是由于这些方法调用的时机或上下文不正确导致的。下面是一个封装 uni.request 的示例,同时展示如何在请求过程中正确管理加载提示。

首先,我们封装一个 request 函数,这个函数返回一个 Promise,并在请求开始和结束时分别调用 uni.showLoadinguni.hideLoading

// request.js
import { uni } from '@dcloudio/uni-mp-weixin'; // 根据实际平台调整import路径

function request(url, method = 'GET', data = {}, header = {}) {
    return new Promise((resolve, reject) => {
        uni.showLoading({ title: '加载中...' });
        
        uni.request({
            url,
            method,
            data,
            header,
            success: (res) => {
                uni.hideLoading();
                if (res.statusCode === 200) {
                    resolve(res.data);
                } else {
                    reject(new Error(`Error: ${res.statusCode}`));
                }
            },
            fail: (err) => {
                uni.hideLoading();
                reject(err);
            }
        });
    });
}

export default request;

接下来,在你的页面或组件中,你可以通过 async/await 来调用这个封装好的 request 函数:

// pages/index/index.vue
<script>
import request from '../../utils/request.js'; // 根据实际路径调整

export default {
    data() {
        return {
            data: null,
            error: null
        };
    },
    async mounted() {
        try {
            const response = await request('https://api.example.com/data', 'GET');
            this.data = response;
        } catch (error) {
            this.error = error.message;
        }
    }
};
</script>

在这个例子中,我们确保了 uni.showLoading 在请求发送前调用,而 uni.hideLoading 在请求成功或失败后调用。这样可以避免因为请求时间过长或失败而导致的加载提示未能正确隐藏的问题。

如果你的 uni.showLoadinguni.hideLoading 仍然报错,请检查以下几点:

  • 确保 uni 对象在你的环境中是有效的,特别是如果你是在某些特定的平台或环境下运行。
  • 检查是否有其他代码(如全局错误处理器)干扰了这些方法的执行。
  • 查看控制台输出的具体错误信息,以便更精确地定位问题。
回到顶部