回调函数中的参数列表是规定好的么???(java 过来的 ,是不是我有什么思维定势) - CNode技术社区

回调函数中的参数列表是规定好的么???(java 过来的 ,是不是我有什么思维定势)
发布于 9 年前 作者 TianYongwei 5624 次浏览 来自 问答

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

可是源码里里面没有说啊 ,这到底是怎么回事? 谢谢

14 回复

约定好的?有相关的说法吗

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 嗯,谢谢。看到了。 xxxx11.png

api 上说的很清楚。这么说来看源码反而是有点扰乱思路了。因为源码并不能看懂多少[笑哭]。

我顺带着看了其他的api, 确实对callback的参数列表都有说明。

(跟看java的api不同的是,java只需要看readFile的参数列表,node的api你还要看看回调函数的参数列表,readFile的参数列表和readFile回调函数的参数列表你都知道的时候才能开始写程序。)

Thank you all.

@TianYongwei nodejs所有的官方api都这个形式的,源码的证据我没找过

@TianYongwei 这是个公认的约定吧,这样写,大家都会处理正确的处理异常;和java的throws catch throw区别略大的

  1. 看API文档。
  2. 看源码。

来自酷炫的 CNodeMD

回到顶部

AltStyle によって変換されたページ (->オリジナル) /