我有这样一段代码(来自这个问题):
var walk = function(dir, done) {
var results = [];
fs.readdir(dir, function(err, list) {
if (err)
return done(err);
var pending = list.length;
if (!pending)
return done(null, results);
list.forEach(function(file) {
file = path.resolve(dir, file);
fs.stat(file, function(err, stat) {
if (stat && stat.isDirectory()) {
walk(file, function(err, res) {
results = results.concat(res);
if (!--pending)
done(null, results);
});
} else {
results.push(file);
if (!--pending)
done(null, results);
}
});
});
});
};
我试着跟着看,我想我什么都懂了,除了接近结尾的地方说!——待定。在这个上下文中,该命令做什么?
编辑:我感谢所有进一步的评论,但这个问题已经回答过很多次了。谢谢!
解释
这是2个算子,a !还有一个——
!--x
x减1,然后!如果x现在为0(或NaN…)则返回true,如果不是则返回false。你可能会把这个习语理解为“我们递减x,如果它变成0……”
如果你想让它更具可读性,你可以:
var x = 1
x = x - 1
if(!x){ //=> true
console.log("I understand `!--` now!")
}
x //=> 0
试试吧:
/* This is an example of the above, you can read this, but it is not needed for !-- */function interactive(a){$("span.code").keydown(function(e){if(13==(e.keyCode||e.which)){var t=$(this);t.clone().html("code").insertAfter(t.next().next()).show().focus().after(template.clone().removeClass("result-template").show()).next().after("<br>"),interactive(),e.preventDefault()}}).keyup(function(e){13!=(e.keyCode||e.which)&&run()})}var template=$(".result-template").hide(),code=$("span.code");code.attr("contenteditable","true").each(function(e,t){template.clone().removeClass("result-template").insertAfter(t)}),interactive(),$.fn.reduce=[].reduce;function run(){var b=!1,context={};$("span.code").each(function(){var a=$(this),res=a.next().show().removeClass("error");try{with(context)res.html(b?"":" //=> "+eval(a.text()))}catch(e){b=e,res.html(" Error: "+b.message).addClass("error")}})};run();
/* This is an example of the above, you can read this, but it is not needed for !-- */span.result.error{display:block;color:red}.code{min-width:10px}body{font-family:Helvetica,sans-serif}
<!-- This is an example of the above, you can read this, but it is not needed for `!--` --><span class="result result-template"> //=> unknown </span> <h2>Edit This Code:</h2><code><span class="code">x = 1</span><br><span class="code">!--x</span><br><span class="code"> x </span><br></code> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
调试(测试代码)
许多答案描述了这个命令的功能,但没有说明为什么要这样做。
我来自C语言的世界,我读!- pending的意思是“倒数pending,检查它是否为零”,而不是真正地思考它。我认为使用类似语言的程序员应该知道这个习语。
该函数使用readdir获取文件和子目录列表,我将它们统称为“条目”。
变量pending会跟踪这些数据中还有多少需要处理。它开始时是列表的长度,随着每个条目的处理,它向下计数到零。
这些条目可能会被无序地处理,这就是为什么有必要进行倒数,而不是仅仅使用一个简单的循环。处理完所有条目后,将调用回调done以通知原始调用方这一事实。
在第一次调用done之前加上return,并不是因为我们想要返回一个值,而只是为了让函数在那一刻停止执行。如果放弃返回并将替代方法放在else中,代码会更简洁。