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

发布于 7 年前作者 chao618105 次浏览最后编辑 7 年前来自 ask

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

10 回复
tanjun
tanjun1 楼6 年前

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

  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')
    })
  },
})
  1. 可以放在 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(){}
})
asun
asun2 楼6 年前

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

maping
maping3 楼6 年前

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

schen
schen4 楼6 年前

先贴代码

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.这个方法来源于官方的示例代码。

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

heping
heping5 楼6 年前
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值,获取不到数据,各位大佬帮忙看下,怎么样解决啊

caowei
caowei6 楼6 年前

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

yang29
yang297 楼6 年前

app.js

WXOPEN Club 内容图片

page.js

WXOPEN Club 内容图片

当然,callback可以传参

uchen
uchen8 楼6 年前

看上图中的loginSuccessCallback

xielei
xielei9 楼6 年前

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

ogong
ogong10 楼5 年前

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