2

刚刚学习了 ember.js,并开始使用ember-app-kit构建一个应用程序。

我正在使用提供的 api-stub 来存根 api,但我决定读入外部 json 文件以用作“夹具数据”。这个决定的原因 - 我将使用相同的 json 文件来测试我的 ember 应用程序以及 rails api 后端。是我的 json 文件示例的要点。

所以我api-stub/routes.js目前看起来像这样:

工作实施

var path = require('path');
var fs = require('fs');
// going to sibling directory
var fixtureDir = path.resolve(__dirname, '../..', 'lightfixtures')

module.exports = function (server) {

    // Create an API namespace, so that the root does not
    // have to be repeated for each end point.
    server.namespace('/api', function () {

      var locationsProtocol = JSON.parse(fs.readFileSync(fixtureDir + '/locations.json'));
      var roomsProtocol = JSON.parse(fs.readFileSync(fixtureDir + '/rooms.json'));

      // stub location list request
      server.get(locationsProtocol[0].request.url, function (req, res) {
        res.send(locationsProtocol[0].response.data);
      });

      // stub individual location request
      server.get(locationsProtocol[1].request.url, function (req, res) {
        res.send(locationsProtocol[1].response.data);
      });

      // stub room list request
      server.get(roomsProtocol[0].request.url, function (req, res) {
        res.send(roomsProtocol[0].response.data);
      });

      // stub individual room request
      server.get(roomsProtocol[1].request.url, function (req, res) {
        res.send(roomsProtocol[1].response.data);
      });
    });
  };

因此,在读取文件并解析其中的部分以存根适当的请求时工作正常 - 但看起来非常多余。我想遍历解析的 json 并为所有元素生成存根,将其干燥并轻松添加更多存根,如下所示:

期望的实现

...
var locationsProtocol = JSON.parse(fs.readFileSync(fixtureDir + '/locations.json'));
var roomsProtocol =     JSON.parse(fs.readFileSync(fixtureDir + '/rooms.json'));

function respondToEach(json) {
  for (var i = 0; i < json.length; i++) {
    server.get(json[i].request.url, function (req, res) {
      res.send(json[i].response.data);
    });
  }
}

respondToEach(locationsProtocol);
respondToEach(roomsProtocol);
...

但它失败了!Ember 抛出默认错误,并在网络窗格中声称它收到内部服务器错误 (500),并且响应部分显示“TypeError:无法读取未定义的属性‘响应’”(指示的行是这一行 -res.send(json[i].response.data);

我很困惑——我认为工作实现和“期望的”实现应该产生完全相同的输出——但事实并非如此。有人可以帮助我了解我在哪里失败(即重构版本有何不同),也许我可以如何解决这个问题?

4

1 回答 1

2

您遇到了臭名昭著的 javascript 循环关闭问题 :) 每个匿名函数内部i最终将成为评估时的lengthof 。json

像这样的东西应该工作

function respondToEach(json) {
  for (var i = 0; i < json.length; i++) {
    (function(idx){
      server.get(json[idx].request.url, function (req, res) {
        res.send(json[idx].response.data);
      });
    })(i);
  }
}

或者您可以定义另一个函数,这将解决关闭问题

function realResponse(item){
  server.get(item.request.url, function (req, res) {
    res.send(item.response.data);
  });
}

function respondToEach(json) {
  for (var i = 0; i < json.length; i++) {
    realResponse(json[i]);
  }
}
于 2014-01-28T04:46:05.660 回答