Javascript 节点js中的回调函数与返回函数

Javascript 节点js中的回调函数与返回函数,javascript,node.js,function,callback,Javascript,Node.js,Function,Callback,我是NodeJS的新手。看来回调函数是在节点中编写函数的标准。这是真的吗?与返回结果的函数相比,编写回调函数有哪些优点?什么时候应该编写回调函数,什么时候应该只使用NodeJS中的常规返回函数 节点服务器是单线程的(对于应用程序代码),您在节点中执行回调的原因是允许线程在等待输入/输出时腾出时间进行其他处理。通常这意味着您只需使用所有调用的异步版本(例如fs.readFile),而不是同步版本(例如fs.readFileSync) 如果您正在创建一个模块,并且在模块内部执行异步调用,那么您将编写

我是NodeJS的新手。看来回调函数是在节点中编写函数的标准。这是真的吗?与返回结果的函数相比,编写回调函数有哪些优点?什么时候应该编写回调函数,什么时候应该只使用NodeJS中的常规返回函数

节点服务器是单线程的(对于应用程序代码),您在节点中执行回调的原因是允许线程在等待输入/输出时腾出时间进行其他处理。通常这意味着您只需使用所有调用的异步版本(例如fs.readFile),而不是同步版本(例如fs.readFileSync)

如果您正在创建一个模块,并且在模块内部执行异步调用,那么您将编写类似的异步调用。然后您的调用者需要向您提供一个回调,您可以调用该回调来返回结果


您也可以使用类似promise的库来返回承诺。

回调是不适合人类使用的低级接口。您应该使用生成器、承诺、异步或其他方式包装回调

这样做的最终好处是可以轻松地同时执行任务

例如,此语法:

var arr = [];
for (var i = 0; i < 10; ++i) {
    arr.push(readSomeFile());
}
var arr=[];
对于(变量i=0;i<10;++i){
arr.push(readSomeFile());
}
将始终意味着一次读取一个文件,任何编译器或transpiler都无法知道所有文件读取都可以同时完成。所以,如果读取1个文件需要10毫秒,则此代码需要100毫秒才能运行,而运行可能只需要10毫秒

对于这两种不同的方法,您不能使用相同的语法

但是,您可以非常接近:

var Promise = require("bluebird");
var fs = Promise.promisifyall(require("fs"));

Promise.coroutine(function* () {
    var arr = [];
    for (var i = 0; i < 10; ++i) {
        arr.push(fs.readFileAsync(...));
    }
    arr = yield Promise.all(arr);
})();
var Promise=require(“蓝鸟”);
var fs=承诺、承诺(要求(“fs”);
Promise.coroutine(函数*(){
var-arr=[];
对于(变量i=0;i<10;++i){
arr.push(fs.readFileAsync(…);
}
arr=收益承诺。全部(arr);
})();

这也会读取10个文件,但它们将同时读取,而不是按顺序读取,这是同步语法无法做到的。

异步编程是使用回调的原因。您应该了解更多关于使用javascript进行异步编程的信息。您需要了解异步。“回调是低级接口,不适合人类”,恕我直言,这是不对的。回调可能有问题,但它们是为人类设计的。@vkurchatkin我不是指一般的回调,但具体来说,在将单个异步操作连接在一起的情况下,你必须无知才能有这样的观点-在使用此用例回调时,你需要记住大约20个问题,这远远超过任何其他上下文中使用的任何其他构造。问自己“如果这个回调在这里被多次调用怎么办?如果这行同步抛出怎么办?”并且更经常地问自己,因为你只是想做一些完全微不足道的事情,否则就是荒谬的。当然,唯一可行的方法是如果你完全不知道这些问题,因此,你必须无知才能发现它们是有用的。nodejs.org frontpage上的buggy hello world示例确实证明了这种无知。回调有问题,你必须思考很多,这是正确的。但你所说的是,没有人在使用它们,每个人都在使用承诺。那不是真的。@vkurchatkin哦,这根本不是我说的,我说你不应该像现在这样使用原始回调API,而是应该用promises/generators/async(曹兰的库)等抽象它们