在Node.js中传播错误回调,并避免所有额外的错误?

时间:2016-03-17 02:19:37

标签: javascript node.js express callback

我正在Node / Express中编写API。我需要一个端点,当你点击它时,它会对外部API执行三次API调用,然后将结果存储在Mongo中。基本上是数据库刷新。

我是节点,异步编程,回调等的新手,所有这些都让我头晕目眩。这就是我到目前为止所拥有的。我主要担心的是我如何处理错误。我可以看到它工作的唯一方法是执行类似下面的操作,将调用传递回我的每个函数,然后如果存在错误,则返回带有error参数的回调,依此类推,直到它冒回到顶部快递服务器可以创建适当的响应。这一切看起来都非常丑陋,而且非常随意,每个功能都有额外的参数,而且流程没有多大意义,我觉得必须有更好的方法。

我知道有承诺,而且我对承诺解决方案持开放态度,特别是如果这是做这些事情的标准方式,但我也想知道我应该如何在经典的javascript中这样做。

var app = require('express')();
var request = require('request');

app.put('/refresh', function(req, res) {
  updateDatabase(function (error) {
    if (error) {
      res.sendStatus(500);
    } else {
      res.send(200);
    }
  });
});

function updateDatabase(callback) {
  var handleErrors = function (error) {
    if (error) {
      return callback(error);
    }
  }
  id1 = 'uniqueId1';
  id2 = 'uniqueId2';
  id3 = 'uniqueId3';
  putLatestStuff(id1, handleErrors);
  putLatestStuff(id2, handleErrors);
  putLatestStuff(id3, handleErrors);
  callback();
} 

function putLatestStuff(id, callback) {
  request('http://api.com/stuff/' + id, putIntoMongo(error, response, body, callback));
  callback();

function putIntoMongo(error, response, body, callback) { // ??? all these parameters now required
  // obviously not correct code
  mongodriver.add(body, anotherFreakingCallback(callback));
}

function anotherFreakingCallback(error, result, callback) {
  if (error) {
    return callback(error);
  }
  callback();
}

这个设计非常糟糕,我确信我做错了。

1 个答案:

答案 0 :(得分:0)

根据每个人的建议,承诺最终成为解决问题的方法。

var app = require('express')();
var fetch = require('isomorphic-fetch');

app.put('/refresh', function(req, res) {
  var ids = ['uniqueId1', 'uniqueId2', 'uniqueId3'];
  updateDatabase(ids)
    .then(function (result) {
      res.status(200).send(result);
    })
    .catch(function (error) {
      res.status(500).send({error: error});
    });
});

function updateDatabase(uniqueIds) {
  var promises = [];
  uniqueIds.forEach(function (id) {
    promises.push(putLatestStuff(id));
  });
  return Promise.all(promises);
} 

function putLatestStuff(id) {
  return getLatestData(id)
    .then(putIntoDatabase);
}

function getLatestData(id) {
  return fetch('http://api.com/stuff/' + id);
}

function putIntoDatabase(data) {
  return mongo.put(data); // mongo.put is fake function that returns a promise
}