Promise.race()怎么知道先返回是哪一个请求???

发布于 2022-09-11 15:30:16 字数 797 浏览 21 评论 0

比较读取本地缓存和请求接口数据的速度,如果是本地缓存先返回的那么无所谓, 但如果是请求接口先返回的那么会导致后来的本地缓存的旧结果把请求接口的新数据给替换掉了,怎么避免这种情况呢???

相关代码

// 第一个请求 获取缓存到本地的数据
function getLocal(storageKey) {
    return new Promise((resolve, reject) => {
        wx.getStorage({
            key: storageKey,
            success(res) {
                resolve(res.data);
            },
            fail(error) {
                reject(error);
            },
        });
    });
}
// 第二个请求 获取接口返回的数据
function getRequestApi(options) {
    return request({
        url: '',
        data: {
            ...options,
        }
    });
}

// 请求的页面中
Promise.race([getLocal('storageKey'), getRequestApi(options)]).then(//希望在这里能判断出是谁先执行完返回的);

上面代码是我打算用Promise.race来进行比较,但是发现只能拿到先返回的数据 但是并不能确定是哪个请求先完成的。。。怎么解决呢????

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

勿忘初心 2022-09-18 15:30:16

promise.race会返回最开始执行完成的那个promise结果,而不管这个请求操作是resolve的还是rejected,在你上面的场景里,你可以在每一个操作的返回结果中注入标签,比如下面的操作方式:

// 第一个请求 获取缓存到本地的数据
function getLocalStorage(storageKey) {
    return new Promise((resolve, reject) => {
        wx.getStorage({
            key: storageKey,
            success(res) {
                // 这里在结果里添加了 raceTag 这样一个标签
                resolve(Object.assign({}, res.data, {raceTag: 'getLocalStorage'}));
            },
            fail(error) {
                reject({raceTag: 'getLocalStorage', error});
            },
        });
    });
}
// 第二个请求 获取接口返回的数据
function getHandPickShop(options) {
    return request({
        url: `${config.API_BASE_URL}/presell/v2/home_info_reform`,
        data: {
            ...options,
        },
        needTokenWhenHad: true,
        withoutToken: true,
    }).then(res => {
        return {raceTag: 'getHandPickShop', ...res}
    }).catch(error => {
        return {raceTag: 'getHandPickShop', error}
    });
}

// 请求的页面中
Promise.race(getLocalStorage('pickShopList'), getHandPickShop({
    city_id: cityId,
    latitude,
    longitude,
})).then(({raceTag}) => {
    // 两个操作的返回结果都封装了raceTag,直接通过raceTag来识别是哪个操作完成
    console.log(`最先完成操作的是:${raceTag}`)
});
阳光下的泡沫是彩色的 2022-09-18 15:30:16

getHandPickShop放在getLocalStorage后再执行
如果没有localStorage这执行getHandPickShop, 否则直接返回
不需要用到race

行至春深 2022-09-18 15:30:16

看了同事最后正确的写法,自己理解着模拟了一段代码出来,大致的逻辑思想是不变的。
有两个点是开始做的时候没有注意的:
1、异步请求赋值 var getLocal = getRequest(2000).then((res) => res)
这样保证了只请求一次
2、Promise.race()函数,只用来处理一种情况 就是getLocal正确返回数据并把数据放到页面上

<body>
    <div id="testId">test</div>
</body>
function setData(data) {
    document.getElementById('testId').innerHTML = data;
}

var mainFun = async function () {
    try {
        var getRequest = function(dealy){
            console.log('开始--' + dealy);
            return new Promise(function(resolve) {
                setTimeout(function () {
                    resolve(dealy)
                }, dealy);
            })
        }
        var getLocal = getRequest(2000).then((res) => res)
        var getRequestApi = getRequest(3000).then((res) => res)
        /**
        * 1、local 成功 request 任意: 取local
        * 2、local 失败 request 任意: 无效,抛"local失败"异常
        * 3、request 成功 local 任意: 无效,抛"request成功"异常
        * 4、request 失败 local 成功: 取local
        * 5、request 失败 local 失败: 无效,抛"local失败"异常
        */
        Promise.race([getLocal, getRequestApi.then(
            () => Promise.reject(new Error('request 先成功')),   // 第3种情况
            () => getLocal        // 第4种情况
        )]).then(
            (data) => {    // 第1和4种情况
                setData(data);
                console.log(data);
            },
            (error) => {    // 第2和5种情况
                console.log(error.message)
            },
        )
        setData(await getRequestApi)    // 比较完成后会把getRequestApi请求的返回值拿到,并去设置到页面上
    } catch(error) {
        console.log(error.message);
    }
}
mainFun()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文