收藏
回答

wx.request无法同步

框架类型 问题类型 API/组件名称 终端类型 微信版本 基础库版本
小程序 需求 wx.request 微信iOS客户端 6.5.3 2.7.7

问题概述

小程序request请求是异步的特性,app.js onLaunch()中的请求与index.js onLoad()中的请求是同时进行的,导致onLoad()中如有基于onLaunch()返回的数据的请求,会有报错,这样会使onLoad()中request请求的数据“第一次”无法正常获取。

我的小程序中所有的requset请求都需要在header中带着用户唯一的token进行发起,而token是在app.js onLaunch()中的wx.login()返回中获取到的(由code到后台换取),之后通过wx.setStorageSync('token', res.data)存到小程序中。 问题是index.js执行需要前面的返回结果时 前面的请求结果还没返回

目前是每个页面加回调,要经过n次判断。这样对于开发真的很不友好。

希望官方可以 让开发者控制 wx.request 同步或异步

回答关注问题邀请回答
收藏

6 个回答

  • 冰是沉默的水
    冰是沉默的水
    2019-10-15

    在app.js的globalData里定义一个用来接获取通过promise的方式openid的变量,在index页面通过全局变量的resolve去请求其他接口,这种方式可以解决app.js获取数据不及时,导致首页获取数据出问题

    2019-10-15
    有用 1
    回复
  • 陈式坚
    陈式坚
    2019-08-05

    这个和wx.request是同步还是异步没啥关系,你的需求是

    『如何提前获取和保存token』

    这个需求很常见,有很多解决方法。

    从思路上有几种常用的解决方法

    1. 在每次request的时候,判断是否有token,没有就先请求(相当于request的before钩子)

    2. 在每次进入页面时,判断是否有token,没有就请求(相当于Router的before钩子)

    你可以自己适合哪种就用哪种


    当然,最友好也是最常用的肯定是第二种。但是第二种有个坏处是,小程序暂时还不能支持router的before钩子,你可以通过框架或者AOP去解决。一劳永逸,所以推荐用这种

    2019-08-05
    有用 1
    回复 2
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-08-05
      1.目前没接触过小程序aop之类,大佬可否介绍下呢? 2.解决方法肯定是有的 但是仍然觉得有同步对于开发真的好很多。 3.还有一些场景 比如打开小程序是否显示welcome页面根据后台能配置。
      2019-08-05
      回复
    • 陈式坚
      陈式坚
      2019-08-06回复哎呦,又忘了×××

      一般小程序框架都可以解决,可以试一下。

      如果纯原生也行,我举个例子

      // app.js


      const _page = Page;
      Page = (opt = {}) => {
        const onLoad = opt.onLoad;
        if (!onLoad) {
          opt.onLoad = function onLoads() {};
        }
        opt.onLoad = function onLoads(query) {
          // 这里去处理token
          onLoad.call(this, query);
        };
       
        _page(opt);
      };


      welcome这个话,估计会被产品干死... 不过如果是自己做就没关系

      2019-08-06
      2
      回复
  • Api调用师
    Api调用师
    2023-07-07

    小程序app与page异步问题的最佳实践? - 微信开放社区 https://developers.weixin.qq.com/community/develop/article/doc/00002ac57208f0e7335d111f156013

    2023-07-07
    有用
    回复
  • Karl
    Karl
    2019-09-12

    楼主有没有解决这个问题,同没办法

    2019-09-12
    有用
    回复 4
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-09-12
      没办法的只能麻烦一点,各种判断回调来解决, 你可以看下上面各位大佬的意见
      2019-09-12
      回复
    • Karl
      Karl
      2019-09-12回复哎呦,又忘了×××
      我这里对所有request做了封装,没token都去登录,造成的问题就是一个页面N个接口,都需要token,完了就登录接口被刷N次,也没有更优美的办法解决了
      2019-09-12
      回复
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-09-12回复Karl
      极端才会n次吧 我们也会调多次(我们加了开屏页 不点跳过只会调一次)
      2019-09-12
      回复
    • Karl
      Karl
      2019-09-12回复哎呦,又忘了×××
      网络不好的情况下会多次重试登录
      2019-09-12
      回复
  • 原初魔鬼
    原初魔鬼
    2019-08-05

    试试自定义一个路由拦截器,所有页面都要经过路由,在路由里可以判断有没有token,有就放行,没有就登录后再放行

    2019-08-05
    有用
    回复 1
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-08-05
      感谢回答, 这样也是可以的,这样可能会出现这个接口 同时此请求,只能说某些场景还是能有选择的好
      2019-08-05
      回复
  • 卢霄霄
    卢霄霄
    2019-08-05

    我上一个小程序是做了个welcome页面,在welcome页面去设token,放到 App 里

    2019-08-05
    有用
    回复 9
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-08-05
      是一种办法,但是如果在公众号菜单配置了去某个页面。还是有这种问题。 还是希望官方能加个参数,这样可以解决很多开发问题,不止是这一个场景
      2019-08-05
      回复
    • 卢霄霄
      卢霄霄
      2019-08-05回复哎呦,又忘了×××

      我在welcome里整合了所有入口,比如,你从公众号要进一个商品的详情页面,

      /pages/welcome?scene=1,1320

      其中第一位 1 这个是我自己定义的静态变量,表示页面,是商品详情;后面的1320是页面的参数 id。在welcome拿到token后,再redirectTo到商品详情页面。

      2019-08-05
      回复
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-08-05回复卢霄霄
      这确实一个非常棒的方法。 如果这个产品设计中没有welcome呢? 或者说需求是welcome页面是否显示,是由于后台动态配置的呢?
      2019-08-05
      回复
    • 卢霄霄
      卢霄霄
      2019-08-05回复哎呦,又忘了×××

      如果只是token的问题,那你可以封装下请求,token没回来的时候要把后续方法都放到一个队列里,token回来之后再依次执行。封装的时候记得留个标识,页面onUnload的时候可以清理下。

      我主管猜测上,把request改成了同步,你在onLanch里调用,如果超时可能会影响小程序加载。不然为啥 setStorage 这都可以做同步,请求没理由不做呢。

      2019-08-05
      回复
    • 哎呦,又忘了×××
      哎呦,又忘了×××
      2019-08-05回复卢霄霄
      是的呢,这样的话就可以影响到页面周期函数的执行流程了,我觉即使影响了也没关系呀
      2019-08-05
      回复
    查看更多(4)
登录 后发表内容