如何优雅的让小程序的request请求支持callback & Promise的写法

前言

随着Promise在被广泛的使用和解决回调地狱的问题,以至于我们只要在发ajax请求的时候就会想起来去使用它。最近在使用小程序的请求request就想当然的使用then的方式来获取结果,然并卵。。。

就去小程序官网巴拉下资料小程序文档链接, 仔细翻阅得到结果如下:

异步 API 返回 Promise

基础库 2.10.2 版本起,异步 API 支持 callback & promise 两种调用方式。当接口参数 Object 对象中不包含 success/fail/complete 时将默认返回 promise,否则仍按回调方式执行,无返回值。

注意事项:部分接口如 request 等等, 它们的 promisify 需要开发者自行封装。

那么我们就来对request 封装,使它支持callback & promise 两种调用方式

一、关于Promise的一些基本介绍和使用

此处只是简单的概述一些基本理念和表现形势,以帮助能理解后续的实现(没有基础的同学,自行度娘和google)

Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。

一般表示形式为:

new Promise(

    /* executor */

    function(resolve, reject) {

        if (/* success */) {

            // ...执行代码

            resolve();

        } else { /* fail */

            // ...执行代码

            reject();

        }

    }

);

二、关于Object.defineProperty的简单描述,(后面会对request重新定义需要用到对象的该方法)

解释:

Object.defineProperty() 会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

语法:

Object.defineProperty(obj, prop, descriptor)

obj:要定义属性的对象。

prop:要定义或修改的属性的名称

descriptor:属性描述符。

用法:

const obj = {};

Object.defineProperty(obj, 'age', {

    value: 24,

    writable: false

});

console.log(obj.age);

// expected output: 42

//对象obj拥有了属性age,值为24

属性描述符说明:

configurable: 当且仅当configurable为true时,改属性描述符才能够被改变,也能被删除

enumerable: 当其值为true时,该属性才能够出现在对象的枚举属性中,默认为false

writable: 当且仅当该属性的值为true时,该属性才能被赋值运算符改变, 默认为false。

value: 该属性对应的值,可以是任意有效的javascript的值(数值,对象,函数等),默认为undefined

*个人尝试,writable为false时也是可以赋值的,可参考上面案例。

三、尝试对小程序的Request方法的一些属性的修改

首先要保证原始对象的一些原有方法和属性不能被改变,所以需要先保存原始对象,然后克隆新对象

通过上述第二点的Object.defineProperty 的方法来修改现有的属性,在请求之前、成功和失败之后处理

具体实现的代码如下:

//接收原对象

const originWx = wx;

//基于WX创建个新对象

wx = Object.create(wx);

//下面尝试对wx.request一些成功失败进行尝试改写

Object.defineProperty(wx, 'request', {

    writable: false,

    value: function(e) {

        console.log('request start...', e);

        // do  something ....

        const success = arguments[0].success;

        const fail = arguments[0].fail;

        //对成功的方法重写定义

        arguments[0].success = function(...args) {

            console.log('request success');

            // do  something ....

            success(...args);

        }

        //对失败的方法重写定义

        arguments[0].fail = function(...args) {

            console.log('request fail');

            // do  something ....

            fail(...args);

        }

        //确保原来的request执行

        originWx['request'].apply(this, arguments);

    }

});

四、通过Promise来实现request能同时满足callback和then的使用

如何让request能满足then的使用,我们先来看看request最原始的用法

wx.request({

  url: 'example.php', //仅为示例,并非真实的接口地址

  data: {

    x: '',

    y: ''

  },

  header: {

    'content-type': 'application/json' // 默认值

  },

  success (res) {

    console.log(res.data)

  },

  fail (err) {

    console.log(err)

  }

})

那么要能同时到达wx.request({url, data, header}).then()的使用和原始的使用改如何分析呢?

通过上述的标黄调用方式,不难发现request的请求参数options对象里面是不包含 success

那么我们是否可以通过是否有success回调函数来区别处理

没有success回调,那么then该怎么实现呢,这时候就该我们Promise出场了,在没有回调函数的时候,我们是否可以直接返回一个Promise

最终改版后的代码实现如下:

//接收原对象

const originWx = wx;

//基于WX创建个新对象

wx = Object.create(wx);

//下面尝试对wx.request一些成功失败进行尝试改写

Object.defineProperty(wx, 'request', {

    writable: false,

    value: function(e) {

        console.log('request start...', e);

        // do  something ....

        const success = arguments[0].success;

        if (success) {

            const fail = arguments[0].fail;

            //对成功的方法重写定义

            arguments[0].success = function(...args) {

                console.log('request success');

                // do  something ....

                success(...args);

            }

            //对失败的方法重写定义

            arguments[0].fail = function(...args) {

                console.log('request fail');

                // do  something ....

                fail(...args);

            }

            //确保原来的request执行

            originWx['request'].apply(this, arguments);

      } else {

          //没有回调走promise

            return new Promise((resolve, reject) => {

                //没有传内部给定一个success回调

                arguments[0].success = function(...args) {

                    console.log('request promise success');

                    // do  something ....

                    resolve(...args);

                }

                //没有传内部给到一个fail回调

                arguments[0].fail = function(...args) {

                    console.log('request promise fail');

                    // do  something ....

                    reject(...args);

                }

                //确保原来的request执行

                originWx['request'].apply(this, arguments);

            });

      }

    }

});

以上是对{小程序的request请求支持callback & Promise的写法}分享~

关于Webfunny


Webfunny专注于微信小程序、H5前端、PC前端线上应用实时监控,实时监控前端网页、前端数据分析、错误统计分析监控和BUG预警,第一时间报警,快速修复BUG!支持私有化部署,容器化部署,可支持千万级PV的日活量!

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容