获取头像的方法失效了

来源:4-1 开锁页面的实现_1

TOM_QI

2021-03-28 02:09:53

老师,获取头像的操作这里不能进行了

http://img.mukewang.com/climg/605f742809834b4911310443.jpg 

vscode里提示没有 resolveUserInfo

到微信里编译后也有这个提示。



 - error TS2339:  Property 'resolveUserInfo' does not exist on type 'Instance<IAppOption>'.


13         getApp<IAppOption>().resolveUserInfo(userInfo)

                                ~~~~~~~~~~~~~~~


写回答

1回答

TOM_QI

提问者

2021-03-31

好吧 我来自问自答吧。

  • 其实视频中的代码由于和新版小程序的代码出入比较大,以至于视频中小程序的示例原代码在现在的版本中不存在,导致去理解原来的这段代码比较困难。


我们先来看app.ts 在老版本中要优化的一段代码

...

wx.getSetting({

    success: (res) =>{

        if ( 从res中获取并判断权限 如果存在 ) {

            wx.getUserInfo({

                success: (info) => {...},

                fail: (err) => {...}

            })

        }

    },

    fail:(err) => {

    }

})

...

这段代码 目的是为了获取用户相关信息,获取用户信息的方法微信提供的 wx.getUserInfo方法,但wx.getUserInfo是否调用 需要根据用户当前的授权情况而决定,所以为了获取用户当前的授权情况就先调用了wx.getSetting,如果用户不授权 就不调用wx.getUserInfo

  ----------

 | 流程如下 |

  ----------

wx.getSetting -----(有权限时)-----> wx.getUserInfo


值得注意的是wx.getSetting和wx.getUserInfo 本质上是微信封装的通过网络请求来获取对应数据的方法,所以这个过程中存在异步处理,而方法中的形参上的 success和fail正是 提供的回调函数的传值处。


这里的弊端其实就是通常的 回调地狱的问题,对于多个请求之间存在依赖的场景 ,需要请完一个再请求另一个的情况 可以通过Promise来进行解决,这是es6之后一种常见的方案之一。所以视频里第一部分 就对这里进行了优化。视频讲解在( 5-5 ) 

--------------app.onLaunch--------------------------------------------

getSetting().then((res=> {

      if (res.authSetting['scope.userInfo']) {

        return getUserInfo()

      }

      throw new Error("用户未授权!")

 }).then(res => {

      resolveUserInfo(res.userInfo)

}).catch(rejectUserInfo)

--------------------------------------------------------------------------

这里resolveUserInfo和rejectUserInfo 会在实际打开的页面的onLoad中从外部传递过到app.ts中(具体方法看一下视频吧)

  • 提问:

  • ​但这里如何保证 上面代码执行时 resolveUserInfo和rejectUserInfo 一定已经收到了来自页面onLoad时传递的回调函数 我是有疑惑的!!!麻烦老师看到解答一下。


然后后面就演示了当用户进入小程序时,用户没有授权的情况,这里在微信的设计中 就要求小程序的开发者只能以提供授权交互的方式供用户自己选择点击,而不能由开发者通过代码直接来调用请求用户授权。


这里另一个知识点是,小程序 请求用户授权的方法 视频里没有提供代码的调用方式,只提供一个拿到用户结果后处理的回调函数的插入方式,像下面这样,可能是微信并没有提供api的调用方式??从安全的角度来说大概是故意这样设计的。

<button class="cu-avatar round lg bg-grey" open-type="getUserInfo" bindgetuserinfo="onGetUserInfo"/>


bindgetuserinfo这里就是填收到结果时处理的回调函数onGetUserInfo


基于这样的情况下 就开始另一个思考是能不能复用之前的代码。其实我上面提供的代码已经是 ( 5-6 ) 优化后的代码了,就是为了增加对onLoad周期中传过去的回调函数进行复用,而定义了一个统一的复用方式


async onLoad(){
  await getApp<IAppOption>().globalData.userInfo?.then((res) => {
     this.setData({
       avatarURL: res?.avatarUrl
     })
  })
},
onGetUserInfo(e:any){
  const userInfo: WechatMiniprogram.UserInfo = e.detail.userInfo
  getApp<IAppOption>().resolveUserInfo(userInfo)
}


基于以上整体流程如下

  ++++++++++                                    ++++++++++++++                           ++++++++++++

 | app onLaunch |-----用户已授权----> | 执行 resolverUserInfo | -------------->| 页面获取到用户信息 |

  +++++|+++++                                   ++++++++++++++                           ++++++++++++

              ↓                                               +++++++++++++++++++++++++
              --------------用户未授权----> | 执行 rejectUserInfo,后续引导用户授权 |

                                                               +++++++++++++++++++++++++



0
hcmouse
hp>同学也可以结合视频中promise的讲解再来理解一下

https://class.imooc.com/lesson/1764#mid=40790


h021-04-17
共9条回复

0 学习 · 1399 问题

查看课程