This is the sixth day of my participation in the August Text Challenge.More challenges in August

preface

I’ve been looking at some source libraries lately, but I’ve been seeing Thunk function a lot. To be honest, I’m new to it and I don’t really know what it is. So holding a thorough understanding of the principle, to query. For example, in the co source code, convert the thunk function to promise.

source

The Thunk function has been around since the 1960s.

At that time, programming languages were still in their infancy, and computer scientists were still figuring out how compilers could write well. One area of contention is the “evaluation strategy,” which is exactly when a function’s parameters should be evaluated

What to make of the above paragraph? Look at a few 🌰

const x = 1

function a(b) {
    return b * 2
}

b(x + 1)

Copy the code

So when is this x plus one going to be executed? Do you calculate it when you pass it, or do you calculate it when you use it?

1.B of x plus is computed as it passes1) => b(2)

2.Calculate it when you use itfunction a(b) {
    return (x + 1) * 2= >return 2 * 2
}
Copy the code

This can result in wasted performance if evaluated at the time of value passing. Because I probably figured it out and didn’t want to use it.

function a(b, c) {
    return c
}
const x = 1.1
a(x^1999, b)

Copy the code

So some people will support a generic call, and that name is called the thunk function.

Thunk function

Show me your code.

Continue with the previous 🌰

const x = 1

function a(b) {
    return b * 2
}

b(x + 1) thunk ===> convertconst x = 1

function a(b) {
    return b() * 2
}
thunk (x) {
    return x + 1
}
b(thunk)
Copy the code

The original x+1 is replaced by the thunk function.

This is the definition of the Thunk function, which is an implementation strategy for “calling by name” to replace an expression.

The chunk function in JS is slightly different. What’s the difference?

Chunk function in JS

The chunk function in JS is basically to change a function with multiple arguments into a single argument function and only accept a callback function as an argument.

What do you mean, go to code

// Normal version of readFile (multi-parameter version)
fs.readFile(fileName, callback);
// Single-parameter version
var readFileThunk = Thunk(fileName);
readFileThunk(callback);
var Thunk = function (fileName){
   return function (callback){
     return fs.readFile(fileName, callback); 
   };
 };
Copy the code

The single-argument version above is a chunk function. Any function whose argument has a callback function can be written as a chunk function.

const Thunk = function(fn){
    const args = Array.prototype.slice.call(arguments)
    return function (cb) {
        args.push(cb)
        return fn.apply(this, args)
    }
    
}

var readFileThunk = Thunk(fs.readFile);
readFileThunk(fileA)(callback)
Copy the code

thunkify

Thunkify This is a nodeJS library

conclusion

The main purpose of the thunk function is to separate data from callbacks.

Such as:

const fs = require('fs');
const readFile = thunkify(fs.readFile);

// This is a collection of execution functions
const f1 = readFile('./a.js')
const f2 = readFile('./b.js')
const f3 = readFile('./c.js')


f1((err, data) = > {
    f2((err, data) = > {
        f3((err, data) = >{})})})Copy the code

But the nesting above is disgusting, so can we use genrator function to improve?

function* gen {
    const res1 = yield f1()
    const res2 = yield f2()
    const res3 = yield f3()
}

const val1 = gen().next().value
const val2 = gen().next().value
const val3 = gen().next().value
Copy the code

At this point, can we use CO to solve the problem that needs next?

So this is going to tie in with what we’ve already learned.

If you think you have written well, click 👍 and pay attention to it