了解function(错误,数据)callback

所以我很困惑如何函数(err,数据)callback工作,是第一个参数总是一个error handling程序?

如果你有一些像函数(x,y,z,a,b,c)那么剩下的参数呢?

fs.readFile中的数据如何从代码的第一行传递到代码的底部? 或换句话说,fs.readFile的输出如何被放入数据参数?

fs.readFile(pathToFile, function (err, **data**) { bufferString = **data**.toString(); 

我可以用函数(x,y)和函数(x,y,z,a,b,c)replace函数(err,data)

但只有第二个参数的作品(数据和Y),这只是JavaScript的callback语法?

例如,这是工作代码以asynchronous读取文件并打印给定文件的行数:

 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); 

callback的调用者(在这种情况下是readFile方法)决定传递给callback的参数。 您需要声明您的callback以匹配readFile将传递给callback的内容。 你可以命名任何你想要的参数(你使用的名字不重要),但是它们将按照readFile决定顺序获取值。

在这种情况下, fs.readFile()使用代码中的两个参数callback(err, data) fs.readFile()调用callback函数。

以下是node.js文档的示例:

 fs.readFile('/etc/passwd', function (err, data) { if (err) throw err; console.log(data); }); 

callback的参数取决于如何调用callback。 例如:

 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; }; 

那么你会像这样使用它:

 var addIdx = function(x,i){ return x+i }; map([1,2,3], addIdx); //=> [1,3,5] 

通过一个简单易懂的例子,您可以编写自己的使用callback函数的版本,很简单:

 function getTwoStringsAsync(callback) { setTimeout(function() { callback("foo", "bar"); }, 1000); } 

这里,函数getTwoStringsAsync预先假定“callback”是一个函数,它暗示着签名(两个参数是string)。 你的方法的消费者可以自由地遵守隐含的签名。 它可以使用这些值中的一个或两个,或者两者都不使用。 但是,如果它假定有两个以上的参数,那么这些参数将显示为未定义的。

 getTwoStringsAsync(function() { console.log("done!"); }); getTwoStringsAsync(function(first, second) { console.log("got " + first + ", " + second); }); getTwoStringsAsync(function(first, second, third) { console.log(third); }); // "undefined" 

这可以说是一种限制,或者是一种力量,或者像Javascript那样的弱types语言,那么函数签名将不会被validation。 强types语言可能会在上面的第一个或第三个用途中生成编译器错误或警告。

当你调用一个函数时,它可以返回一个值或者抛出一个错误。

所以这个同步代码的“等价”

 try { var data = functionCall(); //Use data } catch(err) { console.log(err); } 

这是asynchronouscallback:

 functionCallAsync(function(err, data) { if (err) { console.log(err); } else { //Use data } }); 

你现在可以看到为什么在callback中使用多个值是没有意义的。 事实上,这种模式是有害的。

例如,在使用生成器时,您只能使用单个返回值。 但是,如果一些无知的图书馆作者继续打破了这个callback惯例并且使用了多个,那么这是不可能的。

 async(function* () { try { //What if `functionCallAsync` was called back with multiple values? var data = yield functionCallAsync(); //Use data } catch(e) { console.log(e); } });