- The doTask function has two parameters, iterations and callback
- This function is called twice (COMMENTED OUT)
- Why does the function work when it only receives one argument???
The output in case a 6 is rolled --> 1 2 3... 6 A 6 has been rolled
In case a 6--> 123...[1, 2, 4, 3, 5, 4, 5, 4, 6, 7] is not returned
I guess it would make more sense and it also works if on the first call the callback
had two arguments (true and the result object)
function doTask (iteraciones, callback){
const numbers=[];
for(let i=0; i<iteraciones; i++){
const number=1 +parseInt(Math.random()*6);
numbers.push(number);
console.info(number);
if(number==6){
callback({ error: true, message:" 6"}); //LLAMADA-->AQUÍ SÓLO HAY UN
//ARGUMENTO, CUANDO LO LÓGICO SERÍA UN
// TRUE ,{error:true, message:" 6"}
return;
}
}
//si termina el bucle y no ha salido un 6
return callback(null, {error: false, value: numbers});//LLAMADA--> AQUÍ SI HAY 2
//ARGUMENTOS,NULL(ENTIENDO QUE
//FUNCIONA COMO FALSE) Y EL
//OBJETO
}
doTask(10, function(err, result){
if(err){
console.error("Se ha sacado un ", err.message); //AQUÍ TENDRÍA SENTIDO
//result.message
return;
}
else {
console.log("Tiradas correctas: ", result.value);
}
});
It is a convention. Callbacks receive an eventual error as the first parameter and an eventual result as the second ditto .
Although strictly speaking you could do it as you pose in your question:
And then check the output as:
You would be asking for trouble. The structure of result will be uncertain since it was up to you to know it beforehand. More uncertainty means more complexity in the code to handle it.
The convention goes further, and in light of it your implementation doesn't comply either: it
err
should be an object of typeError
and not a plain object (let alone aboolean
)Although your callback, like all callbacks, expects a second parameter, you can invoke it with a single argument. Javascript has never had a problem with this. That path leads to
result
beundefined
and that's not a problem unless you want to treat it as an object or a function. For example if you were to ignore that the callback returned an error:Why follow convention?
Let's think that within the scope where your procedure occurs you have other logic that gets its results from a database, a call to an external API, etc. Those libraries would use the convention and you would have to handle the output of the callback in one way, and your function in another. Case by case. If you stick to the convention, however, you'll be able to handle errors homogeneously, even with a common handler:
And better yet, send the error upstream to be handled by a higher handler.
You could also promisify your function using
Almost all libraries today support invocation with callback as using promises, indistinctly, so you could chain the calls from the penultimate example to avoid introducing a race condition
If your callback uses something other than an error as its first parameter, the above won't gracefully handle a roll of 6. Node will tell you: "Promise rejected with a non error"