In the process of developing a small program recently, I met a requirement that the header should be accompanied with accessToken when requesting. AccessToken is a parameter returned through the login interface, and it may be expired, so I need to log in again. Therefore, the locally stored accessToken verification will be performed every time the applets are loaded. However, under the operation mechanism of applets, the onLaunch of APP and the onLoad of Pages will be executed concurrently. In the case of weak network, concurrency may lead to incomplete accessToken verification. The page request function starts executing. It is easy to cause an interface exception. The original solution would be to await the checkAccessToken method in app.js before each page calls the interface, but this is not very friendly to write

Solution:

An additional layer of lock is encapsulated on the basis of request. Before accessToekn check is completed, all other incoming requests are waited. Other requests are not requested until the check is completed

The principle of analysis

  1. Encapsulate the original request
  2. Make use of the feature of Promise and the feature of JS object stored in memory, together with async/await, make other requests wait for the key request to complete before starting the request, so as to realize the request lock
  3. First wait for the critical request to complete, and then go back to determine whether it is needed

The code analysis

First, simulate a request

Const mockRequest = (name, time = Math.random() * 1000) => new Promise(reslove => { console.log(`${name}---------------run`); setTimeout(() => { reslove(`${name}---------------done`); }, time); });Copy the code

Define request lock

The request lock manages two states, one is the critical request is in progress state, the other is when the critical request fails, need to wait for the auxiliary operation to complete state

const lock = { wait: null, runing: null };

Copy the code

Add a layer of encapsulation on top of request

  1. Parameter Settings: withOutLock is used to skip logic for certain requests that do not need to wait, and lockOthers is used to lock requests that come in after critical requests
  2. Critical requests come in and are executed directly,lock.runingPending status is assigned to a key request directly. When other requests come in, the request is not initiated, and the other requests are executed only after the main request is completed
Const request = async (name, opts = {withOutLock: false, lockOthers: false, hasErr: If (opts.withoutLock) {const res = await mockRequest(' ${name} - withOutLock '); if (opts.withoutLock) {const res = await mockRequest(' ${name} - withOutLock '); console.log(res); return; } / / key request completes Other request has reached the awaited state if (lock. Running) {the console. The log (` ${name} -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- wating... `); await lock.runing; } if (opts.lockothers) {lock.runing = mockRequest(name, 4000); let res = await lock.runing; // Empty to lock. Runing = null; If (opts.haserr) {lock. Wait = mockRequest(" key request exception handling ", 4000); } else { console.log(res); return; If (lock.wait) {console.log(' Waiting for critical request exception processing... `); await lock.wait; // Empty wait lock lock.wait = null; Console. log(' Critical request exception handling completed '); } const res = await mockRequest(name); console.log(res); return; };Copy the code

Simulated operation effect

Const mockConcurrent = () => {for (let I = 0; i < 5; I++ {setTimeout () () = > {request (` concurrent requests ${I} `, {withOutLock: I = = = 0}). }, Math.random() * 100); }}; Request (" Critical requests - others must wait to complete ", {lockOthers: true, hasErr: false}); mockConcurrent();Copy the code

Runtime effect

The last

After my colleague’s advice, I plan to explore the request pool and implement the request context in the future

Demo code: Specific example code demo reference

Pure technical exploration, pit point unknown, welcome to point out mistakes and deficiencies