如何处理Node.js中的回调?

时间:2015-10-20 02:31:39

标签: node.js callback

假设我有3个文件。

index.js像这样调用后端

renderer:updateAtTime:

routes.js像这样处理路线

$.post('/test/', data, function(response) {
 //handle success here
})

items.js是访问数据库并为每个项目发出POST请求的模型

app.post('/test/', function(req, res){
   item.getItems(function(response){
     res.json(response);
   });
 });

where /何时应该调用传递给getItems()的回调来处理index.js中的成功/失败?

2 个答案:

答案 0 :(得分:2)

由于您的request.post()操作是异步的,因此您必须使用某种方法来跟踪它们何时完成,然后您可以调用回调。有多种方法可以做到这一点。我将概述几个:

手动跟踪请求操作的数量

function getItems(callback) {
  database.query('SELECT * from items', function(result){
    var remaining = result.length;
    result.forEach(function(item){
        request.post('/api/', item, function(err, res) {
          --remaining;
          //finished posting item
          if (remaining === 0) {
              callback();
          }
        });
    });   
  });
}

手动执行此操作的主要问题是,当您真正弄清楚如何处理错误时,嵌套异步操作中的传播错误很困难。这在此处显示的其他方法中要容易得多。

使用承诺

// load Bluebird promise library
var Promise = require('bluebird');

// promisify async operations
Promise.promisifyAll(request);

function queryAsync(query) {
    return new Promise(function(resolve, reject) {
        // this needs proper error handling from the database query
        database.query('SELECT * from items', function(result){
            resolve(result);
        });
    });
}

function getItems(callback) {
    return queryAsync('SELECT * from items').then(function(result) {
        return Promise.map(result, function(item) {
            return request.postAsync('/api/', item);
        });
    });
}

getItems.then(function(results) {
    // success here
}, function(err) {
    // error here
})

答案 1 :(得分:1)

您在服务器端代码中发出API请求似乎很奇怪,除非这是与API交互的某种中间层代码......但您正在与数据库进行交互,所以我仍然对为什么你不能进行数据库插入或者进行批量插入API调用感到困惑?

无论如何,如果你必须按照你提出的方式去做,我过去用一种减少结果数组的递归方法来做到这一点......我真的不知道如果这是一个好方法,所以我想听听任何反馈。像这样:

function recursiveResult(result, successfulResults, callback) {
  var item = result.shift();
  // if item is undefined, then we've hit the end of the array, so we'll call the original callback
  if (item !== undefined) {
    console.log(item, result);
    // do the POST in here, and in its callback, call recursiveResult(result, successfulResults, callback);
    successfulResults.push(item);
    return recursiveResult(result, successfulResults, callback);
  }
  // make sure callback is defined, otherwise, server will crash
  else if (callback) {
    return callback(successfulResults);
  }
  else {
    // log error... callback undefined
  }
}

function getItems(callback) {
  var successfulResults = [];
  var result = [1, 2, 3, 4];
  recursiveResult(result, successfulResults, callback);
}

console.log('starting');
getItems(function(finalResult) {
  console.log('done', finalResult);
});