nodeJs回调简单示例


120

谁能给我一个NodeJs回调的简单示例,我已经在许多网站上进行了搜索,但无法正确理解,请给我一个简单的示例。

getDbFiles(store, function(files){
    getCdnFiles(store, function(files){
    })
})

我想做这样的事情...


一个关于如何编写一个以回调为参数的函数的例子?
Gntem

是的,像这样的例子,任何可以帮助我理解它的简单示例。
Bhushan Goel

2
回调是您作为参数传递给另一个函数的函数... Google pls->“回调javascript”->第一个结果
Gabriel Llamas

Answers:


198
var myCallback = function(data) {
  console.log('got data: '+data);
};

var usingItNow = function(callback) {
  callback('get it?');
};

现在打开节点或浏览器控制台,并粘贴以上定义。

最后在下一行中使用它:

usingItNow(myCallback);

关于节点样式错误约定

Costa问如果我们要遵守节点错误回调约定,会是什么样子。

按照这种约定,回调应期望至少收到一个参数(第一个参数)作为错误。根据上下文,我们可以选择有一个或多个其他参数。在这种情况下,上下文就是我们上面的示例。

在这里,我按照这个约定重写了我们的示例。

var myCallback = function(err, data) {
  if (err) throw err; // Check for the error and throw if it exists.
  console.log('got data: '+data); // Otherwise proceed as usual.
};

var usingItNow = function(callback) {
  callback(null, 'get it?'); // I dont want to throw an error, so I pass null for the error argument
};

如果要模拟错误情况,可以像这样定义usingItNow

var usingItNow = function(callback) {
  var myError = new Error('My custom error!');
  callback(myError, 'get it?'); // I send my error as the first argument.
};

最终用法与上面的完全相同:

usingItNow(myCallback);

行为上的唯一区别将取决于usingItNow您所定义的版本:将“真实值”(错误对象)提供给第一个参数的回调的回调,或将其提供给错误参数为null的回调。


那么,将错误作为第一个参数约定,这看起来像什么?
哥斯达黎加

113

回调函数只是您传递给另一个函数的一个函数,以便该函数可以在以后调用它。这在异步API中很常见;API调用会立即返回,因为它是异步的,因此您将一个函数传递给它,API完成异步任务后就可以调用该函数。

我能想到的最简单的示例是JavaScript setTimeout()函数。这是一个接受两个参数的全局函数。第一个参数是回调函数,第二个参数是延迟(以毫秒为单位)。该函数旨在等待适当的时间,然后调用您的回调函数。

setTimeout(function () {
  console.log("10 seconds later...");
}, 10000);

您可能之前已经看过上面的代码,但没有意识到所传递的函数称为回调函数。我们可以重写上面的代码以使其更明显。

var callback = function () {
  console.log("10 seconds later...");
};
setTimeout(callback, 10000);

由于Node是从头开始构建的,因此在其所做的所有操作中都是异步的,因此在Node的各处都使用了回调。即使在与文件系统对话时。这就是为什么大量内部Node API接受回调函数作为参数,而不是返回可以分配给变量的数据的原因。相反,它将调用您的回调函数,将所需的数据作为参数传递。例如,您可以使用Node的fs库读取文件。该fs模块公开了两个独特的API函数:readFilereadFileSync

readFile函数是异步的,而readFileSync显然不是。您会看到他们希望您尽可能使用异步调用,因为它们调用了它们readFilereadFileSync而不是readFileand readFileAsync。这是同时使用这两个功能的示例。

同步:

var data = fs.readFileSync('test.txt');
console.log(data);

上面的代码将阻止线程执行,直到将所有内容test.txt读入内存并存储在变量中为止data。在节点中,这通常被视为不良做法。有时候,它很有用,例如编写一个快速的小脚本来完成一些简单而乏味的事情,而您并不在乎可以节省每一纳秒的时间。

异步(带回调):

var callback = function (err, data) {
  if (err) return console.error(err);
  console.log(data);
};
fs.readFile('test.txt', callback);

首先,我们创建一个接受两个参数err和的回调函数data。异步函数的一个问题是捕获错误变得更加困难,因此许多回调样式的API将错误作为回调函数的第一个参数传递。最佳实践err是在执行其他任何操作之前检查是否具有值。如果是这样,请停止执行回调并记录错误。

当引发异常时,同步调用具有优势,因为您可以简单地用一个try/catch块捕获它们。

try {
  var data = fs.readFileSync('test.txt');
  console.log(data);
} catch (err) {
  console.error(err);
}

在异步函数中,它不是那样工作的。API调用会立即返回,因此没什么用try/catch。正确的使用回调的异步API会始终捕获其自身的错误,然后将这些错误传递给回调,您可以在其中视需要处理它。

但是,除了回调外,还有另一种流行的API样式,称为promise。如果您想阅读有关它们的信息,则可以阅读我根据此处的答案撰写的整个博客文章。


3
相当详尽而简洁地表达了这一概念;对于像我这样的node.js初学者...
kmonsoor

3
+1用于提供大量上下文。不仅回调函数看起来像什么,回调函数是什么,为什么使用它们,以及为什么经常使用它们。对初学者很有帮助。
Azurespot '18 -10-4

1
大!这可能是一个帖子!
Pablo Glez,

1
是的,其中包括有关承诺的第二部分;)
Chev

1
这是比公认答案更好的解释!我在这里这么爱每一个接受的答案是这样的-不仅是一段代码,解决问题,同时也是WHYHOW它解决了这个问题。基本上,此答案和回调将使您对什么是回调有一个相当扎实的理解。
RusI

10

这里是复制文本文件的例子fs.readFilefs.writeFile

var fs = require('fs');

var copyFile = function(source, destination, next) {
  // we should read source file first
  fs.readFile(source, function(err, data) {
    if (err) return next(err); // error occurred
    // now we can write data to destination file
    fs.writeFile(destination, data, next);
  });
};

这是使用copyFile函数的示例:

copyFile('foo.txt', 'bar.txt', function(err) {
  if (err) {
    // either fs.readFile or fs.writeFile returned an error
    console.log(err.stack || err);
  } else {
    console.log('Success!');
  }
});

常见的node.js模式表明回调函数的第一个参数是错误。您应该使用此模式,因为所有控制流模块都依赖于此模式:

next(new Error('I cannot do it!')); // error

next(null, results); // no error occurred, return result

2
接下来是什么?什么是变量results =被称为什么?
游牧编码者,2014年

3
@SemicolonWarrier为我以及其他人提供了一个指针: stackoverflow.com/questions/5384526/javascript-node-js-next
kmonsoor

7

尽量简单地尝试一下此示例,只需复制save newfile.js做node newfile即可运行该应用程序。

function myNew(next){
    console.log("Im the one who initates callback");
    next("nope", "success");
}


myNew(function(err, res){
    console.log("I got back from callback",err, res);
});

3

我们正在创建一个简单的功能

callBackFunction (data, function ( err, response ){
     console.log(response)
}) 

// callbackfunction 
function callBackFuntion (data, callback){
    //write your logic and return your result as
callback("",result) //if not error
callback(error, "") //if error
}

1
const fs = require('fs');

fs.stat('input.txt', function (err, stats) {
    if(err){
        console.log(err);
    } else {
        console.log(stats);
        console.log('Completed Reading File');
    }
});

“ fs”是一个节点模块,可以帮助您读取文件。回调函数将确保在执行之前完全读取名为“ input.txt”的文件。fs.stat()函数用于获取文件信息,例如文件大小,创建日期和修改日期。


1

//delay callback function
function delay (seconds, callback){
    setTimeout(() =>{
      console.log('The long delay ended');
      callback('Task Complete');
    }, seconds*1000);
}
//Execute delay function
delay(1, res => {  
    console.log(res);  
})


0

A callback是作为参数传递给Higher Order FunctionWikipedia)的函数。回调的简单实现为:

const func = callback => callback('Hello World!');

要调用该函数,只需将另一个函数作为参数传递给已定义的函数。

func(string => console.log(string));

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.