【问题标题】:nodeJs callbacks simple examplenodeJs 回调简单示例
【发布时间】:2013-11-13 10:05:58
【问题描述】:

谁能给我一个简单的nodeJs回调示例,我已经在很多网站上搜索过但无法正确理解,请给我一个简单的例子。

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

我想做这样的事情......

【问题讨论】:

  • 一个关于如何编写一个将回调作为参数的函数的示例?
  • 是的,类似的,任何可以帮助我理解的简单示例。
  • 回调是作为参数传递给另一个函数的函数... Google pls -> "callback javascript" -> first result

标签: javascript node.js asynchronous callback asynccallback


【解决方案1】:
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。

【讨论】:

  • 那么当错误作为第一个参数约定时,这是什么样的呢?
【解决方案2】:

回调函数只是您传递给另一个函数的函数,以便该函数可以在以后调用它。这在异步APIs中很常见; 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 而不是 readFilereadFileAsync。这是使用这两个函数的示例。

同步:

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

首先我们创建一个回调函数,它接受两个参数errdata。异步函数的一个问题是捕获错误变得更加困难,因此许多回调风格的 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。如果您想了解它们,那么您可以阅读我基于此答案 here 撰写的整篇博文。

【讨论】:

  • 概念的精巧而简洁的表达;对于像我这样的 node.js 初学者...
  • +1 用于提供大量上下文。不仅回调函数长什么样,还有它们是什么,为什么使用它们,以及为什么它们被大量使用。对初学者真的很有帮助。
  • 太棒了!这可能是一个帖子!
  • It is,它包括一个关于承诺的second part ;)
  • 这是一个比公认答案更好的解释!我希望这里的每一个接受的答案都是这样的——不仅是解决问题的一段代码,还有它解决问题的 WHYHOW问题。基本上,这个答案和 callbackhell 会让你对什么是回调有一个非常扎实的理解。
【解决方案3】:

这里是一个用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

【讨论】:

【解决方案4】:

尽可能简单地尝试这个示例,只需复制 save newfile.js do 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);
});

【讨论】:

    【解决方案5】:

    我们正在创建一个简单的函数

    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
    }
    

    【讨论】:

      【解决方案6】:
      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() 函数用于获取文件信息,如文件大小、创建日期和修改日期。

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

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

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

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

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

          【讨论】:

            【解决方案9】:

            这篇博文写得很好:

            https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced

            function doHomework(subject, callback) {
              alert(`Starting my ${subject} homework.`);
              callback();
            }
            
            function alertFinished(){
              alert('Finished my homework');
            }
            
            doHomework('math', alertFinished);

            【讨论】:

              猜你喜欢
              • 2014-01-05
              • 1970-01-01
              • 2018-05-03
              • 2015-02-10
              • 2013-01-13
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多