Problems often encountered from a front end

  • For example, what do I do if I want to listen for all fetch requests in a project? Or, I want to use someone else’s wrapped method, but before I do that, I need to go through a layer of processing, judgment, and then see if I can call someone else’s wrapped method
  • This demand, mostly similar, remember I explained before KOA onion rings, Redux middleware and other source code is a core problem solving way of thinking in our front end

How do I listen for fetch requests

  • For example,fetchThe use of, generally:
fetch(url).then((res)=>{... })Copy the code
  • So for a project that has been used many times, I need to listen for this fetch request. What should I do? It’s very simple. We rewrite.fetch
const myFetch = window.fetch; window.fetch = function (... Arg) {console.log(" fetch is called now, argument :", arg); return myFetch(arguments); }; fetch("www.baidu.com").then((res) => { console.log(res, "res"); });Copy the code
  • In a few lines of code, you can listen for all the FETCH requests. And it doesn’t interfere with the original functionality, but here’s the problem

  • By doing so, you are essentially modifying the method on the prototype chain, contaminating the pure original method. When it comes to the actual operation, it is recommended to write a new method and then replace it globally, so that the underlying method can be guaranteedfetchThe method is normal and does not affect those places that do not need logs, so we will talk about similar source code implementation in passing today

To the essence of redux middleware source codecomposefunction

  • Let’s say we have functions like this:
function add1(str) {
    return str + 1
}

function add2(str) {
    return str + 2
}

function add3(str) {
    return str + 3
}
Copy the code
  • If we want to execute functions in sequence and pass the results to the next layer, we write it layer by layer as follows:
let newstr = add3(add2(add1("abc"))) //"abc123"]
Copy the code
  • This is just three, and if you have a lot of them or if you don’t have a fixed number of them it’s going to be a lot of trouble, but we’re going to usecomposeIt’s elegant to write:
let newaddfun = compose(add3, add2, add1);
let newstr = newaddfun("abc") //"abc123"
Copy the code
So how is compose implemented internally?
function compose(... funcs) { return funcs.reduce((a, b) => (... args) => a(b(... args))); }Copy the code
  • In fact, the core code is a sentence, the code usedreduceMethod neatly converts a series of functionsadd3(add2(add1(... args)))This form, let’s break it down step by step using the example above
  • When callingcompose(add3, add2, add1).Funcs is add3, add2, add1When you first enterA is add3.B is add2The expansion looks like this:(add3, add2) =>(... args)=>add3(add2(... args))And introduced intoAdd3, add2, returns a function like this (... args)=>add3(add2(... args))And thenreduceSo let’s go ahead. The second time we enter, a is the function that we returned from the previous step(... args)=>add3(add2(... args)).B is add1, so execute to a(b(... The args))), b (... Args), passed as arguments to function a, becomes this form :(... args)=>add3(add2(add1(... args)))Isn’t that clever?

If you can’t understand it here, you need to figure it out today even if you don’t go to bed, take paper and write it down to implement the call process, which is the hardest thing in the front end. Remaining source tutorial can see my dead simple: https://github.com/JinJieTan/Peter-

To the promise chain-call implementation

  • PromiseThe chained invocation differs from JQ in that promise.then returns a new promise instance object each time, thus implementing the chained invocation.
  • JQ chain is equivalent to a function that always returns the same this inside of the current one
$('#root').style(...) .style(...)Copy the code
  • Promise the chain, the final printed result isPeter teacher 666Each time. Then returns a new onePromise
Resolve ("Peter teacher 666"). Then ((res) => {return res; }) .then((res) => { console.log(res,'res') return res; });Copy the code

To Express’s Next

  • The next match is entered when we call next() in routing processing, for example when we request the interface with GETtestWhen, will walk toConsole. log(" triggered at this time ")This line of code
App. Get ('/test '(the req, res, next) = > {next ()}) app. Get (' *' (the req, res, next) = > {the console. The log (" trigger at this time ")})Copy the code
  • What’s the reason? Implementing Next for Express is simple
handle(req, res, matchedList) { const next = () => { const midlleware = matchedList.shift(); if (midlleware) { midlleware(req, res, next); }}; next(); }Copy the code
  • We find all matching request modes and routes, and then process the route in the first match first, passing it to the Next method using a closure. When the next method is called, the route callback function in the next match is executed. This implements next

To koA’s middleware

  • How to use KOA’s middleware?
app.use(middlewaer1).use(middlewaer2).use(middlewaer3)
Copy the code
  • If it feels like JQ’s chained call, it will return this. As follows:
const obj = { print(arg) { console.log(arg); return this; }, hello(arg) { console.log(arg); return this; }, world(arg) { console.log(arg); return this; }}; obj.print('Peter').print('hello').print('world');Copy the code
  • The console now printsPeter,hello,world. We implemented the simplest chain call.

In this paper, all the source code parsing in my lot, holiday good learning tool: https://github.com/JinJieTan/Peter-

conclusion

  • Read so much, the most difficult article, I’m afraid iscomposeFunction. In fact, most of the source code is similar, master its essence, to maximize its dregs.
  • If it feels good, do itJust watching/liking/retweetingSanlian bar, pay attention to my public number: [The front-end peakThank you for supporting my original!