The code is from the IPFS (Inter-planetary file-system) HTTP API JS implementation: https://github.com/ipfs/js-ipfs-api/blob/master/src/api/add.js
'use strict'
const Wreck = require('wreck')
module.exports = (send) => {
return function add(files, opts, cb) {
if (typeof(opts) === 'function' && cb === undefined) {
cb = opts
opts = {}
}
if (typeof files === 'string' && files.startsWith('http')) {
return Wreck.request('GET', files, null, (err, res) => {
if (err) return cb(err)
send('add', null, opts, res, cb)
})
}
return send('add', null, opts, files, cb)
}
}
The function being described is the add()
function, used to push data to IPFS.
I'll start by explaining what I do understand: the add()
function takes three arguments – if there is no options
object (the user omitted it) and it's been replaced by a function: the user is trying to implement a callback function instead – change the callback to opts
; cb = opts
.
Secondly, if the cited file is a text file &&
starts with http
– it's obviously hosted remotely and we need to fetch it using Wreck
.
All of this I understand, but why are we using the (send) =>
arrow function? Why do we use return function add...
? What's the send('add', null, opts, res, cb)
and return send('add', null, opts, res, cb)
used for? How is the callback ( cb
) implemented? Help me understand what's happening here
The whole thing being exported is a function , which expects send
as an argument; this lets the calling code do dependency injection by passing in the send
function to use. It's expecting to be used something like this:
let addBuilder = require("add");
let add = addBuilder(senderFunction);
// This function ----^
// is `send` in the `add.js` file.
// It does the actual work of sending the command
// Then being used:
add(someFiles, someOptions, () => {
// This is the add callback, which is `cb` in the `add.js` file
});
(Frequently, the first two statements above are written as a single statement, eg let add = require("add")(senderFunction);
)
Basically, the whole thing is one big builder for something that uses a given send
function, which is injected into it by calling the builder. That way, it can be tested by injecting a testing version of send
, and used for real by injecting a real version of send
; and/or various "real" versions of send
can be used in different environments, transport mechanisms, etc.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.