【问题标题】:How should I handle promises and callbacks with waterline and bluebird?我应该如何使用水线和蓝鸟处理承诺和回调?
【发布时间】:2015-06-20 01:04:58
【问题描述】:

我在使用帆时遇到了多个问题,因为我无法理解水线承诺及其逻辑。

我尝试了内置的 bluebird promises,甚至还尝试了 async.waterfall 实现,但都没有成功。

简而言之,我正在为执行数据库查询的 API 编写代码,并尝试使用回调,但它从不响应。

这是我尝试过的纯承诺:

changeFormation: function (request,response) {

  console.log("changeFormation");
  var lineupId = request.params.id;
  var newFormation = request.param('formation');
  var newLineUp = request.param('lineup');
  console.log("Receiving" + newFormation);

  if ( ["5-4-1", "5-3-2", "4-5-1", "4-4-2", "4-3-3", "3-5-2", "3-4-3"].indexOf(newFormation) === -1 ) {
    console.log("No válida");
    return response.send(409, "La táctica elegida no es válida");
  }

  LineUp.findOne({id: lineupId}).
  then(function (foundLineUp) {

    console.log(foundLineUp);
    if (!foundLineUp)
      return response.send(404);

    if (! foundLineUp.formation) {

      foundLineUp.formation = newFormation;

    LineUp.update({id: foundLineUp.id}, foundLineUp).exec(function (err, saved) {

      if (err)
        return response.send(500, JSON.stringify(err));

      return response.send(202, JSON.stringify(saved));
    });

    }

    // If a formation was previously set
    else if (Array.isArray(newLineUp) &&  newLineUp.length > 0) {

      newLineUp.formation = newFormation;

      LineUp.update({id: newLineUp.id}, newLineUp).exec(function (err,saved) {
        if (err)
          return response.send(500,JSON.stringify(err));
        return response.stringify(202, JSON.stringify(saved));
      });
    }
    console.log("Never reached");
  }).
  catch(function (err) {
    console.log(err);
    response.send(500,JSON.stringify(err));
  });
},

在上面这个我可以在控制台中看到 "Never reached"。为什么!?

这就是我尝试使用异步模块的方式:

addPlayer: function (request,response) {

  // console.log("Add player");
  var lineupId = request.params.id;

  var receivedPlayer = request.param('player');
  var playerId = receivedPlayer.id;
  var bench = receivedPlayer.bench;
  var place = receivedPlayer.place;
  var e, r;

  async.waterfall([

    function (cb) {

      LineUp.findOne().where({id: lineupId}).exec(function (err, foundLineUp) {
        cb(err,foundLineUp);
      });},

    function (lineup,cb) {

      Player.findOne().where({id: playerId}).exec(function (err,foundPlayer) {
        cb(err,lineup, foundPlayer);
      });},

    function (lineup, player, cb) {
      if (!player) {
        console.log("Jugador no existe");
        cb(null, {status: 409, msg: "El jugador " + playerId + " no existe"});
      }

      if (!lineup.formation) {
        console.log("No hay táctica")
        cb(null, {status: 409, msg: "No se ha elegido una táctica para esta alineación"});
      }

      if (lineup.squadIsComplete()) {
        console.log("Ya hay 15");
        cb(null, {status: 409, msg: "La plantilla ya contiene el máximo de 15 jugadores"});
      }

      if (lineup.playerWasAdded(player.id)) {
        console.log("Jugador ya en alineación")
        cb(null, {status: 409, msg: "El jugador ya ha sido agregado a la alineación"});
      }

      if (lineup.fieldIsComplete() && !bench) {
        console.log("Ya hay 11 en el campo");
        cb(null, {status: 409, msg: "Ya se han agregado los 11 jugadores de campo"});
      }

      player.bench = bench;
      player.place = place;

      lineup.players.push(player);

      console.log("MaxForeign " + lineup.reachesMaxForeignPlayers());
      console.log("BudgetLimit " + lineup.reachesBudgetLimit());
      console.log("SameTeam " + lineup.reachesMaxSameTeamLimit());
      console.log("reachesMaxSameFavoriteTeamLimit " + lineup.reachesMaxSameFavoriteTeamLimit());


      // If any of rule restrictions evaluates to true ...
      // Using lodash _.some with out second argument which defaults to _.identity
/*      if ( _.some([ lineup.reachesMaxForeignPlayers(),
                    lineup.reachesBudgetLimit(),
                    lineup.reachesMaxSameTeamLimit(),
                    lineup.reachesMaxSameFavoriteTeamLimit()]) ) {

        return response.send(409, "La inclusión de este jugador no satisface las reglas del juego");
      }*/

      LineUp.update({id: playerId}, lineup).exec(function (err, saved) {
        cb(err, {status: 202, msg: JSON.stringify(saved)});
      });
    }
  ],

  function (err, result) {
    console.log("About to respond");
    if (err)
      respond.send(500);
    else
      response.send(result.status, result.msg);
  });

  console.log("Never reached");
},

这并没有给出超时,但奇怪的是它没有在应该更新文档的时候更新。它正在记录 "never reached" 然后是 "about to respond" 但我猜这很正常。

到目前为止,我应该如何处理这一切?

【问题讨论】:

  • 您为什么希望永远无法联系到console.log("Never reached");?唯一无法达到的情况是发送了 404。
  • 呃,这两个sn-ps的代码似乎完全不相关,并且使用了不同的方法。请只询问每个问题的一个问题(尽管您可能包括多种不同的方法来解决它)

标签: javascript asynchronous sails.js waterline bluebird


【解决方案1】:

在上面,我可以在控制台中看到“从未到达”。为什么!?

因为您将异步代码与同步代码混合在一起。如果你这样做:

function(){
  console.log('init');
  someAsyncMethod(function callback(){
    return console.log('async done');
  });
  console.log('Never reached');
}

你会得到:

init
Never reached
async done

因为异步代码将在之后执行。我建议您阅读 thisthis 以更好地理解异步回调。

这并没有给出超时,但奇怪的是它没有在应该更新文档的时候更新。

很难说发生了什么,因为我们不知道LineUp 的模型定义,也不知道lineupupdate 调用前后的内容。你确定LineUp.update() 跑了吗?为什么不在其回调中添加console.log() 以查看结果?

到目前为止,我应该如何处理这一切?

在我看来,您已接近实现目标。如果您分享LineUp 的模型定义和更多日志记录,我们将能够为您提供更多帮助。

【讨论】:

  • 嘿,感谢您的回复,我确实在我的代码甚至这篇文章中做出了愚蠢的假设。但是我发现了这个问题,这让我完全困惑。我已经发布了一个单独的问题,如果您有使用 Sails 的经验,我希望您可以查看一下:stackoverflow.com/questions/30958122
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-10
  • 2015-10-27
  • 2016-07-26
  • 2016-09-23
  • 1970-01-01
  • 1970-01-01
  • 2015-09-06
相关资源
最近更新 更多