求问,怎么才能先执行app.js,执行完了,才执行page里的js呢

如题,我想在app.js里用接口获取一个参数,用到page里面,显示在页面上,但是每次页面加载完了,app.js才获取到参数,这怎么办呢

最后一次编辑于  01-11  (未经腾讯允许,不得转载)
收藏 0评论 0
关注问题写回答

33 个回答

  • 青痕青痕

    先贴代码

    app.js

    wx.getUserInfo({
              success: res => {
                this.globalData.userInfo = res.userInfo;

               // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回,所以此处加入 callback 以防止这种情况

               if (this.userInfoReadyCallback) {

                  this.userInfoReadyCallback(res);
                };
              },
            })


    page.js

    onLoad: function () {

       // 判断全局的userInfo是否存在

        if (app.globalData.userInfo) {
          this.setData({
            userInfo: app.globalData.userInfo,
          })

        }

       // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回,所以此处加入 callback 以防止这种情况

        else {
          app.userInfoReadyCallback = res => {
            this.setData({
              userInfo: res.userInfo,
            })
          }
        }
      },

    原理:在app.js中加入一个条件判断,若条件中的callback被赋值存在,则传入wx.getUserInfo的参数res。

    在page.js中,判断全局app.globalData.userInfo是否存在,存在则正常赋值。不存在则说明wx.getUserInfo的异步请求晚于page.js的调用,那么就将setData函数赋值给app.js中的callback,callback传入res调用后,page中的userInfo也就被设置好了。


    p.s.这个方法来源于官方的示例代码。

    我的理解是这样,不知道是不是有帮助,如有错误请指出。

    赞同 0没有帮助
    评论 0
    复制
    02-12
  • 第五日凌晨第五日凌晨

    贴的图代码还多了,必要代码就是loginSuccessCallback。你只要理解,多种场景下,app.js中异步请求的同时,page.js已经走了onLoad方法,此时使用只有app.js中请求成功后才可能有值的detail做判断,若detail为空,则给app.js注册一个loginSuccessCallback回调,这个回调方法的执行时机,就是app.js中的异步请求完毕,如图所示,仅此而已。

    赞同 0没有帮助
    评论 0
    复制
    01-16
  • 姜晨姜晨

    大哥,能把代码多贴一点么

    赞同 0没有帮助
    评论 0
    复制
    01-16
  • 第五日凌晨第五日凌晨

    看上图中的loginSuccessCallback

    赞同 0没有帮助
    评论 0
    复制
    01-16
  • 姜晨姜晨
    onLaunch: function () {
         
       // 展示本地存储能力
       var logs = wx.getStorageSync('logs') || []
       logs.unshift(Date.now())
       wx.setStorageSync('logs', logs)
       // 登录
       wx.login({
         success: res => {
           console.log(res.code)
           // 发送 res.code 到后台换取 openId, sessionKey, unionId
           if (res.code) {
             //发起网络请求
             wx.request({
               url: this.globalData.url+'/auth/user/authorize/',
               data: {
                 code: res.code
               },
               success:(res)=>{
                 if(res.data.code == 0){
                 console.log(res)
                 var data=res.data
                 // console.log(data)
                 wx.setStorage({
                   key:'ticket',
                   data:{ticket:data.data.ticket,id:data.data.user_id}
                 })
                 }
               }
             })
           } else {
             console.log('获取用户登录态失败!' + res.errMsg)
           }
         }
       })

    这是app.js部分,获取到ticket值,并且存储起来



    */
    onLoad: function () {
      console.log(1111111111111111+"onload")
      var that = this;
     
      wx.getStorage({
        key: 'ticket',
        success: (res) => {
          console.log(res)
          var ticket = res.data.ticket;
          var id=res.data.id
          that.setData({
            ticket:ticket,
            id:id
          })
        },
      })
    },

    这是index.js中onLoad部分,当我一次进来时拿不到ticket值,手动刷新一下才能拿到


    onReady: function () {
       console.log(this.data.ticket)
       var that = this;
       var ticket = this.data.ticket
       console.log(ticket)
       wx.request({
         url: app.globalData.url +"/source/campus/",
         data: { ticket: ticket, pagination: false },
         success: (res) => {
           console.log(res)
           var item=res.data.data
           if(res.data.code == 0){
           for(var i =0;i<item.length;i++){
             item[i].count=i
             item[i].checked=false
           }
           that.setData({
               item:item
           })
           }
         }
       })
       console.log(ticket)
       console.log(this.data.id)
       wx.request({
         url: app.globalData.url +"/auth/user/info/"+this.data.id+"/?ticket="+this.data.ticket,
         data:{ticket:ticket},
         success:(res)=>{
           if (res.data.code == 0) {
           console.log(res.data.data)
           var temp=res.data.data.wcampus
           var item=that.data.item
           for(var i=0;i<temp.length;i++){
             for(var j=0;j<item.length;j++){
               if(temp[i]==item[j].id){
                 item[j].checked=true
                 console.log(item[j].checked)
                 if(res.data.data.email!=""){
                 that.setData({
                   username:res.data.data.name,
                   userEmail:res.data.data.email,
                   userWechat:res.data.data.wechat,
                   userSchool:res.data.data.cschool,
                   item:item,
                   state:"1"
                 })
                 }
               }
             }
           }
           }
         }
       })
     },

    这是index中onReady部分。要通过上面获取的ticket值,在向后台请求数据时发送过去,才能拿到对应的数据。


    现在问题就是第一次拿不到ticket值,获取不到数据,各位大佬帮忙看下,怎么样解决啊

    赞同 0没有帮助
    评论 0
    复制
    01-15
  • 第五日凌晨第五日凌晨

    app.js


    page.js


    当然,callback可以传参

    赞同 0没有帮助
    评论 0
    复制
    01-15
  • 姜晨姜晨

    试了下,还是没弄好,心累

    赞同 0没有帮助
    评论 0
    复制
    01-15
  • 永恒君永恒君

    唔,怎么看上去有些复杂了呢,分两种吧,

    1. 非要在 app.js 里面运行的

    //app.js
    App({
      onLaunch: function() {
        this.post_entry(res => {
          this.entry_data = res;
          console.log('加载完成')
          this.post_entry_finish(res)
        })

      },

      // 获取数据

      post_entry: function(cb) {
        setTimeout(cb, 2000)

      },

      // 获取数据完成

      // entry_finish 比 post_entry 快,则保存函数
      // post_entry 比 entry_finish 快,则直接运行
      entry_finish: function (cb) {
        if (this.entry_data) {
          cb && cb(this.entry_data)
        else {
          this.post_entry_finish = cb
        }

      },

      // 获取数据完成,在 index.js 再运行部分

      post_entry_finish: function(cb) {
      },
    })
     
    // index.js
    var app = getApp()
    Page({

      onLoad: function () {

        // app.js 里的 post_entry 运行完再运行这个

        app.entry_finish(res => {
          console.log('x')
        })
      },
    })

    2. 可以放在 index.js 里面运行的

    // app.js
    App({
      post_entry: function(cb) {
        setTimeout(cb, 2000)
      },
    })
     
    // index.js
    Page({
      onReady: function () {
        app.post_entry(res => {
          console.log('x')
          this.entry_finish(res)
        })
      },
      entry_finish: function(){}
    })


    赞同 0没有帮助
    评论 0
    复制
    01-15
  • 姜晨姜晨

    请问下,为什么在第一次登陆的时候,不能拿到数据,在刷新后就可以拿到数据库的数据了,这是为什么?

    赞同 0没有帮助
    评论 0
    复制
    01-15
  • 追小命追小命

    把相关的渲染过程写成页面里一个单独的函数,在app执行成功之后通过getCurrentPage后直接调用page里的这个函数

    赞同 0没有帮助
    评论 0
    复制
    01-15