小程序学习 - callback

微信小程序的许多操作都是采取回调的机制(比如网络请求、页面跳转),回调机制简单来说就是在执行某个异步操作的时候会给该异步操作注册一个函数,再在该操作返回结果的时候调用这个函数,以达到异步调用的效果。

小程序的一个标准的网络请求是这样的:

wx.request({
    url: 'test.php',
    header: {
        'content-type': 'application/json' // 默认值
    },
    success: res => {
        console.log(res.data)
    },
    fail: res => {
        console.log(res)    
    }
})

这上面的 success 就是注册了一个匿名箭头函数(es6特性),在网络请求返回成功的结果时输出日志;但如果我要在一个网络请求之后执行下一个网络请求,甚至多个网络请求并行执行的时候,不断地注册函数会导致函数体十分庞大,俗称 回调地狱

针对这一现象,可以使用js中的 Promise 优化回调,比如 wx.request,并封装项目需要的后端服务器地址、cookie机制等内容。

Promise封装wx.request

const http = ({
    url = '',
    param = {},
    content_type = 'application/json',
    ...other
} = {}) => {
    wx.showLoading({
        title: '请求中,请耐心等待..'
    });
    return new Promise((resolve, reject) => {
        wx.request({
            url: getUrl(url),
            data: param,
            header: {
                'content-type': content_type,
                'cookie': wx.getStorageSync("baobaozhuan_cookie") || ''
            },
            ...other,
            complete: (res) => {
                // 保存cookie
                if (res.header && res.header["Set-Cookie"]) {
                    wx.setStorageSync("baobaozhuan_cookie", res.header["Set-Cookie"].split(';')[0])
                }
                wx.hideLoading();
                if (res.statusCode >= 200 && res.statusCode < 300) {
                    resolve(res.data)
                } else {
                    reject(res)
                }
            }
        })
    })
}

代码使用示例

系分课程的项目没有那么多链式异步请求,这里举一个我课外的一个项目的例子

var promise = new Promise(function (resolve, reject) {
            wx.login({
                success: res => {
                    resolve(res)
                },
                fail: res => {
                    reject(res)
                }
            })
        })
        
        promise.then(res => {
            // 发送 res.code 到后台换取 openId, sessionKey, unionId
            return http._post('/common/wxLogin', { wxCode: res.code }, 'application/json')
        }).then(res => {
            var code = res.code;
            var key = res.user_key;
            if (code != 200) {
                throw code
            } else {
                app.globalData.userKey = key;
                app.globalData.isLogin = true;
                wx.setStorageSync('userKey', key)
            }
            return new Promise(function (resolve, reject) {
                wx.getUserInfo({
                    success: res => {
                        resolve(res)
                    },
                    fail: res => {
                        reject(res)
                    }
                })
            })
        }).then(res => {
            const userInfo = res.userInfo
            const nickName = userInfo.nickName
            return http._post('/wx/updateUserInfo', { name: nickName })
        }).then(res => {
            wx.switchTab({
                url: '/pages/index/index'
            })
        }).catch(res => {
            console.log(res)
            wx.showToast({
                title: '登录出现异常! 请联系客服',
                duration: 1500,
            });
              
        })

在promise的封装下,所有异步请求代码形成链式调用的模式,风格清爽,易读性增加 100%

你可能感兴趣的:(小程序学习 - callback)