1.自己写的测试中使用了 fs模块的readFile方法。想知道这个方法的回调为社么这么写? 为什么第一个参数是err,第二个参数是data. 在这个回调中竟然很神奇的拿到了数据
var fs = require("fs");
fs.readFile('input.txt', function (err, data) {
if (err){
console.log(err.stack);
return;
}
console.log(data.toString());
});
console.log("程序执行完毕");
2.然后我就想看看 这个回调是怎么拿到err 和data 的数据的,找到了源码
fs.readFile = function(path, options, callback_) {
var callback = maybeCallback(arguments[arguments.length - 1]);
if (!options || typeof options === 'function') {
options = { encoding: null, flag: 'r' };
} else if (typeof options === 'string') {
options = { encoding: options, flag: 'r' };
} else if (typeof options !== 'object') {
throwOptionsError(options);
}
var encoding = options.encoding;
assertEncoding(encoding);
var flag = options.flag || 'r';
if (!nullCheck(path, callback))
return;
var context = new ReadFileContext(callback, encoding);
var req = new FSReqWrap();
req.context = context;
req.oncomplete = readFileAfterOpen;
binding.open(pathModule._makeLong(path),
stringToFlags(flag),
0o666,
req);
};
function nullCheck(path, callback) {
if (('' + path).indexOf('\u0000') !== -1) {
var er = new Error('Path must be a string without null bytes.');
er.code = 'ENOENT';
if (typeof callback !== 'function')
throw er;
process.nextTick(callback, er);
return false;
}
return true;
}
function ReadFileContext(callback, encoding) {
this.fd = undefined;
this.size = undefined;
this.callback = callback;
this.buffers = null;
this.buffer = null;
this.pos = 0;
this.encoding = encoding;
this.err = null;
}
可是源码里里面没有说啊 ,这到底是怎么回事? 谢谢
约定好的?有相关的说法吗
http://fredkschott.com/post/2014/03/understanding-error-first-callbacks-in-node-js/
这跟nodejs的实现有关么?
来自酷炫的 CNodeMD
回调函数中的参数列表是规定好的,一般以错误(err)优先。关于回调的问题,举个简单的例子。 比如说我有一个函数fun1,需要两个参数,第一个参数是一个数字,第二个参数是一个函数。
function fun1(num,callback){
var str = "您输入的数字是" + num;
//在合适的时候执行回调函数,此时,我们会给回调函数一些参数,注意你此时输入的参数顺序。
callback(null,str);
}
//我们执行fun1
fun1(10,function(err,result){
//因为方法比较简单,并不发生错误,只是举例
console.log(err,result);
});
如你所见,你回调的时候(调用callback)录入的参数顺序,就是fun1中你传递函数中的参数顺序。fs.readFile方法也一样,你传入你的函数之后,他会调用你的回调函数,并按照一定的顺序输出你需要的值,具体顺序可以查看api。
约定大于配置
回调的约定是:
2个参数
function (err, data)
@youthfighter 你好,谢谢你的回答。 你这里举得这个例子我很明白。我在调用fun1的时候看了fun1函数是怎么定义的,自然就能知道回调函数怎么写,最起码我知道有几个参数,还能知道第二个参数的意义,就是我想要的额内容。但是我并不能知道fs.readFile()这个函数的回调有个参数,以及参数的具体意义,因为readFile 在声明的时候并没有想你的fun1函数中的callback(null,str)类似的语句啊。 可能是我看的不够仔细?
@alsotang 谢谢你的回答。 顺便问一下 这个约定能能在源码里面找到证据吗?
你能举个例子来说明问题吗? 谢谢。
@htoooth 谢谢你的回答。 那也就是说,我写回调的时候参数列表一定是这两个吗?还是只有这些node比较基础的模块才会是这样?
这样理解也不对好像,你能在讲下你的理解吗?谢谢。
@TianYongwei 所以你得看api啊,就像你引用一个jar,使用第三方的类,调用第三方的方法public void fun1(a,b,c,d){},你也不能知道a是啥不是?只能查api。 fs.readFile可以查node的rs模块的api。回调函数的参数有这样的描述“回调函数传递了两个参数 (err, data), data 就是文件的内容。”以下是node的api地址,你可以看一下http://nodeapi.ucdok.com/#/api/fs.html。
@TianYongwei 不一定,回调函数的参数没有规定必须有几个,看你的需求。使用第三方模块的话,回调函数有几个参数,得看api。
@youthfighter 嗯,谢谢。看到了。
api 上说的很清楚。这么说来看源码反而是有点扰乱思路了。因为源码并不能看懂多少[笑哭]。
我顺带着看了其他的api, 确实对callback的参数列表都有说明。
(跟看java的api不同的是,java只需要看readFile的参数列表,node的api你还要看看回调函数的参数列表,readFile的参数列表和readFile回调函数的参数列表你都知道的时候才能开始写程序。)
Thank you all.
@TianYongwei nodejs所有的官方api都这个形式的,源码的证据我没找过
@alsotang ok
@TianYongwei 这是个公认的约定吧,这样写,大家都会处理正确的处理异常;和java的throws catch throw区别略大的
- 看API文档。
- 看源码。
来自酷炫的 CNodeMD