Hello. I am currently stuck on this lesson on Promisification. It is not very long. Literally a page, but I am struggling to understand all the little details.
Here is the callback Version of loadScript()
function loadScript(src, callback) {
let script = document.createElement('script');
script.src = src;
script.onload = () => callback(null, script);
script.onerror = () => callback(new Error(`Script load error`));
document.head.append(script);
}
And here is the promisified version loadScriptPromise()
let loadScriptPromise = function(src) {
return new Promise((resolve, reject) => {
loadScript(src, (err, script) => {
if (err) reject(err);
else resolve(script);
});
});
};
Question #1
When loadScript()
is called inside the returned Promise
, are we still using script.onerror
and script.onload
to determine whether reject()
or resolve()
is called? Is the “error first” callback style generally only used with .onload
and .onerror
?
Question #2
What will be accomplished by script.onload = () => callback(null, script)
and resolve(script)
? The script has already been appended to the page. Is it returning something or doing something further with the script? Is it simply just to return a promise and make it chainable with .then()
? And why is script
the result of resolve()
?
Here is a promisify()
function that allows any function to become a Promise
.
function promisify(f) {
return function (...args) { // return a wrapper-function
return new Promise((resolve, reject) => {
function callback(err, result) { // custom callback for f
if (err) {
reject(err);
} else {
resolve(result);
}
}
args.push(callback); // append custom callback to f args
f.call(this, ...args); // call the original function
});
};
}
Question #3
The function f
that we promisify can accept (...args)
as a parameter because of the wrapper, but those (...args)
are never used at all. Are they? And shouldn’t the number of arguments affect the function?
Question #4
What is the custom callback for? It is given arguments err
and result
, but we don’t even know if the function being promisified has err
and result
to begin with. Does the promisified function f
obtain arguments err
and result
because we .push()
the callback()
to args
?
And I have no idea what the following means.
But what if the original
f
expects a callback with more argumentscallback(err, res1, res2, ...)
?We can improve our helper. Let’s make a more advanced version of
promisify
.When called as
promisify(f)
it should work similar to the version above.When called as
promisify(f, true)
, it should return the promise that resolves with the array of callback results. That’s exactly for callbacks with many arguments.
Any help understanding this would be greatly appreciated, as I am completely lost. I do not understand where arrayOfResults
in the usage comes from. I also still do not understand how the callback()
function connects with the promisified function.
// promisify(f, true) to get array of results
function promisify(f, manyArgs = false) {
return function (...args) {
return new Promise((resolve, reject) => {
function callback(err, ...results) { // custom callback
if (err) {
reject(err);
} else {
// resolve with all callback results
// if manyArgs is specified
resolve(manyArgs ? results : results[0]);
}
}
args.push(callback);
f.call(this, ...args);
});
};
}
// usage:
f = promisify(f, true);
f(...).then(arrayOfResults => ..., err => ...);
I know that was quite a bit. Thank you for taking the time to read this post.