Proxy encapsulates asynchronous call of wechat applet

Keywords: Javascript network

Last reply:

Students who didn't look back Here!

// utils/async.js

function wxPromisify(fn) {
    return async function(args) {
        return new Promise((resolve, reject) => {
            fn({
                ...(args || {}),
                success: res => resolve(res),
                fail: err => reject(err)
            });
        });
    };
}

export function toAsync(names) {
    return (names || [])
        .map(name => (
            {
                name,
                member: wx[name]
            }
        ))
        .filter(t => typeof t.member === "function")
        .reduce((r, t) => {
            r[t.name] = wxPromisify(wx[t.name]);
            return r;
        }, {});
}
// pages/somepage/somepage.js

import { toAsync } = require("../../utils/async");

// ...

const awx = toAsync(["login", "request"]);
await awx.login();
await awx.request({...});

Isn't that sealed?

This time it's a different encapsulation. Because, a small program to write many toAsync calls, it's really annoying!

Can I encapsulate it once and call it everywhere? Yes! Encapsulate all methods used during initialization. However, it is inevitable that there will be omissions.

Can we encapsulate once and call everywhere without initialization?

Yes! Sacrifice to the God of Proxy:

// utils/asyncjs

function wxPromisify(fn) { ... }    // As defined earlier

export function asyncProxy(target) {
    return new Proxy(target, {
        cache: {},
        get(it, prop) {
            const aFn = this.cache[prop];
            if (aFn) { return aFn; }
            const v = it[prop];
            if (typeof v !== "function") {
                return v;
            }
            return this.cache[prop] = wxPromisify(v);
        }
    });
}
// app.js
import { asyncProxy } from "./utils/async";

App({
    onLaunch: function() {
        wx.awx = asyncProxy(wx);
        // ....
    }
})
// pages/somepage/somepage
// ...
const { awx } = wx;
await awx.login();
await awx.request({...});

Interpretation:

Because awx is the agent's wx object, when awx.login() is called, the agent's get(wx, "login") is actually called first to find something to replace wx.login.

According to the logic in the above code, first find the result encapsulated by wxPromisify() from the cache, if any, return it directly; if not, first encapsulate it as a function of the Promise network, store it in the cache, and then return it.

It can be described intuitively as follows:

awx.login();
   ^^^^^^
   get(wx, "login")

The last question is: how to encapsulate the situation that there are return values in wx.request()?

Like this article, order one**

Posted by Velausanakha on Thu, 09 Apr 2020 07:31:14 -0700