javascript 了解函数(错误、数据)回调
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20647832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Understanding function (err, data) callbacks
提问by enducat
So I am confused about how the function(err, data) callback works, is the first argument always an error handler?
所以我对 function(err, data) 回调的工作方式感到困惑,第一个参数总是错误处理程序吗?
What about the remaining arguments if you had something like function (x, y, z, a, b, c)?
如果你有函数 (x, y, z, a, b, c) 之类的东西,剩下的参数呢?
How does the data from fs.readFile pass from the top line of code to the bottom line of code? Or in other words, how does the output of fs.readFile get put into the data argument?
fs.readFile 中的数据如何从最上面一行代码传递到最下面一行代码?或者换句话说, fs.readFile 的输出如何放入 data 参数中?
fs.readFile(pathToFile, function (err, **data**) {
bufferString = **data**.toString();
I could replace function (err, data) with function (x, y) and function (x, y, z, a, b, c)
我可以用函数 (x, y) 和函数 (x, y, z, a, b, c) 替换函数 (err, data)
But only the second argument works (data and y), is this just the syntax of javascript callbacks?
但只有第二个参数有效(数据和 y),这只是 javascript 回调的语法吗?
For example, this is working code to asynchronously read a file and print out the number of lines given a file:
例如,这是异步读取文件并打印给定文件的行数的工作代码:
var fs = require('fs');
var pathToFile = process.argv[2];
var bufferString, bufferStringSplit;
function counter(callback) {
fs.readFile(pathToFile, function (err, data) {
bufferString = data.toString();
bufferStringSplit = bufferString.split('\n');
callback();
});
}
function logMyNumber() {
console.log(bufferStringSplit.length-1);
}
counter(logMyNumber);
回答by jfriend00
The caller of the callback (which is the readFile
method in this case) decides what arguments are passed to the callback. You need to declare your callback to match what readFile
says that it will pass to the callback. You can name the arguments anything you want (the names you use do not matter), but they will get values in the order that readFile
decides.
回调的调用者(readFile
在本例中是方法)决定将哪些参数传递给回调。您需要声明您的回调以匹配readFile
它将传递给回调的内容。您可以为参数命名任何您想要的名称(您使用的名称无关紧要),但它们将按照readFile
决定的顺序获取值。
In this case, fs.readFile()
calls the callback with the two arguments you have in your code as in callback(err, data)
.
在这种情况下,fs.readFile()
使用代码中的两个参数调用回调,如callback(err, data)
.
Here's an example from the node.js docs:
这是 node.js 文档中的一个示例:
fs.readFile('/etc/passwd', function (err, data) {
if (err) throw err;
console.log(data);
});
回答by McGarnagle
Easy to understand with an example... you can write your own version of a function that uses a callback, quite simply:
用一个例子很容易理解……您可以编写自己的使用回调的函数版本,非常简单:
function getTwoStringsAsync(callback) {
setTimeout(function() {
callback("foo", "bar");
}, 1000);
}
Here, the function getTwoStringsAsync
is pre-supposing that "callback" is a function, and it implies signature (two parameters that are strings). The consumer of your method is free to adhere to the implied signature or not. It can use one or both of those values, or neither. But if it assumes any more than two parameters, those will appear as undefined.
在这里,函数getTwoStringsAsync
预先假设“回调”是一个函数,并且隐含了签名(两个参数是字符串)。您的方法的使用者可以自由地遵守或不遵守隐含的签名。它可以使用这些值中的一个或两个,或者都不使用。但是,如果它假设有两个以上的参数,则这些参数将显示为未定义。
getTwoStringsAsync(function() { console.log("done!"); });
getTwoStringsAsync(function(first, second) { console.log("got " + first + ", " + second); });
getTwoStringsAsync(function(first, second, third) { console.log(third); }); // "undefined"
It is arguably a limitation, or a strength, or weakly-typed languages like Javascript, that function signatures will not be verified. A strongly-typed language may generate a compiler error or warning in the first or third uses above.
无法验证函数签名可以说是一个限制,或者一个优势,或者像 Javascript 这样的弱类型语言。在上述第一次或第三次使用中,强类型语言可能会产生编译器错误或警告。
回答by elclanrs
The arguments of the callback depend on how the callback gets called. For example:
回调的参数取决于回调的调用方式。例如:
var map = function(xs, f) {
var result = [];
for (var i=0; i<xs.length; i++) {
// Here we call the callback function
// with the element as context, the element as first param
// and the index as second param.
// Extra parameters are `undefined`
result.push(f.call(xs[i], xs[i], i));
}
return result;
};
Then you'd use it like:
然后你会像这样使用它:
var addIdx = function(x,i){ return x+i };
map([1,2,3], addIdx); //=> [1,3,5]
回答by Esailija
When you call a function it can either return a singlevalue or throw a singleerror.
当您调用函数时,它可以返回单个值或抛出单个错误。
So the "equivalent" of this synchronous code:
所以这个同步代码的“等效”:
try {
var data = functionCall();
//Use data
}
catch(err) {
console.log(err);
}
Is this asynchronous callback:
这是异步回调:
functionCallAsync(function(err, data) {
if (err) {
console.log(err);
}
else {
//Use data
}
});
You can see now why it makes no sense to use multiple values in the callback. In fact, such pattern is actively harmful.
您现在可以看到为什么在回调中使用多个值没有意义。事实上,这种模式是有害的。
For example when using generators you are back to only having the possibility of using a single return value. But if some ignorant library author went ahead and broke the callback convention and used multiple, this would be impossible.
例如,当使用生成器时,您只能使用单个返回值。但是如果一些无知的库作者继续打破回调约定并使用多个,这将是不可能的。
async(function* () {
try {
//What if `functionCallAsync` was called back with multiple values?
var data = yield functionCallAsync();
//Use data
}
catch(e) {
console.log(e);
}
});