background
As we all know, ES6 has brought us a new master in the field of meta-operation — Proxy
Advantages over Object.defineProperty:
- The initial quantity is little
- An array of available
- Sensitive to adding and deleting fields
- A variety of intercept
Those who are not familiar with proxy can refer to the following links
Proxy-MDN
The Proxy – ECMAScript 6 primer
The Promise of laziness
Now let’s find some chestnuts to make this lazy Promise come true.
Wechat ecology today, there are still a lot of people silently using the callback, if the control is not good, it is easy to fall into the hell callback, also can not use true fragrance async.
Although there are also a lot of schemes to achieve, but this time let us forget it, with our way to achieve
Our main goal was to make Handle, who can’t wear makeup, an a-list promise
wx.showToast({
title: 'success',
success () {
console.log('success')
},
fail () {
console.log('fail')}})// Here we delegate the WX API to the WXQ variable
wxq.showToast({title: 'success'})
.then(() = > console.log('success'))
.catch(() = > console.log('fail'))
.finally(() = > console.log('finally'))
Copy the code
A single promise
The basic point is to directly encapsulate a function, and then put an API into it every time it is used. However, when using it, there is no aesthetic feeling, the operation is distorted, and there is a layer of shell
function wxPromise(fn, param){
return new Promise((resolve, reject) = > {
const data = Object.assign({
success(res) {
resolve(res)
},
fail(res){
reject(res)
}
}, param)
fn(data);
})
}
wxPromise(wxq.showToast, {title: 'success'})
.then(() = > console.log('success'))
.catch(() = > console.log('fail'))
.finally(() = > console.log('finally'))
Copy the code
The Proxy mode
But before I do that, let’s say that the next time we have a situation like this. Can we continue to reuse some of our code instead of uni-App or some similar framework? How do you design this code
So I decided to split the code into three parts
- Proxy generating function: Proxy according to the Promise template function
- Promise template function: supplement based on context
- Exit functions: Mask some of the generated details
// proxy generates functions
function createProxyAll (obj, fn) {
return new Proxy(obj, {
get(target, key, receiver) {
// The operation receiver loops
if(! target[key]) target[key] = fn(key)return Reflect.get(target, key, receiver); }})}// Promise template function
function wxPromise(key){
// Cache key generates a Promise closure
return function (param) {
return new Promise((resolve, reject) = > {
const data = Object.assign({
success(res) {
resolve(res)
},
fail(res){ reject(res) } }, param) wx[key](data); }}})// Exit function
function wxPromiseAll () {
return createProxyAll(wx, wxPromise)
}
Copy the code
Graceful degradation
Good things are more or less unknown to the world. I have used this scheme before. On a sunny day, the operator rushed to tell me that a customer’s mobile phone was completely blank when opened. I broke out a few drops of sweat in the temperature of 26°.
While (true)} {thinking. PNG
A proxy compatibility problem was detected.
- That’s easy. Ask the customer to change phones.
- Gasket library? Meta operations such as proxy and Object.defineProperty cannot be shipped and are either not supported by the environment or not. This is the direct reason why VUe2 and VUe3 are not compatible with older browsers.
- Do downgrade √ with defineProperty
function make (obj, fn) {
// Determine whether the Proxy needs to be degraded
if (typeof Proxy= = ='function') {
return createProxyAll(obj, fn)
} else {
return createdefinePropertyAll(obj, fn)
}
}
function createdefinePropertyAll (obj, fn) {
const _obj = {}
const result = {}
Object.keys(obj).forEach(key= > {
Object.defineProperty(result, key, {
get() {
// The judgment here is the same as with proxy, preventing reference loops
if(! _obj[key]) _obj[key] = fn(key)return _obj[key]
},
})
})
return result
}
Copy the code
The defineProperty version implements much the same, and you can see that the defineProperty version initialises by directly proxying all fields, which is why vue3 implemented using proxy performs better than VUe2 implemented using defineProperty. Also, why am I saying that this is lazy Promise, that only when you use it, you’re going to intercept it and change it to a Promise, instead of having to initialize it all
The end
The code can be viewed here
How much I want to pick up the phone, I see your comments, better than the goddess