Ответ дублирован, но количество показаний равно 1 - PullRequest
0 голосов
/ 08 января 2019

Использование Dynamoose ORM с Serverless. У меня есть сценарий, в котором я нахожу информацию пользователя на основе рекомендации.

Ответ выглядит следующим образом

{
    "data": {
        "results": [
            {
                "specialTip": "Hello World",
                "recommendation": "Huli ka!",
                "poi": {
                    "uuid": "poi_555",
                    "name": "Bukit Panjang",
                    "images": [
                        {
                            "url": "facebook.com",
                            "libraryUuid": "2222",
                            "uuid": "9999"
                        }
                    ]
                },
                "uuid": "i_8253578c-600d-4dfd-bd40-ce5b9bb89067",
                "headline": "Awesome",
                "dataset": "attractions",
                "insiderUUID": "i_c932e85b-0aee-4462-b930-962f555b64bd",
                "insiderInfo": [
                    {
                        "gender": "m",
                        "funFacts": [
                            {
                                "type": "knock knock!",
                                "answer": "Who's there?"
                            }
                        ],
                        "profileImage": "newImage.jpg",
                        "shortDescription": "Samething",
                        "fullDescription": "Whatever Description",
                        "interests": [
                            "HELLO",
                            "WORLD"
                        ],
                        "tribes": [
                            "HELLO",
                            "WORLD"
                        ],
                        "uuid": "i_c932e85b-0aee-4462-b930-962f555b64bd",
                        "personalities": [
                            "HELLO",
                            "WORLD"
                        ],
                        "travelledCities": [
                            "HELLO",
                            "WORLD"
                        ]
                    }
                ]
            },
            {
                "specialTip": "Hello World",
                "recommendation": "Huli ka!",
                "poi": {
                    "uuid": "poi_555",
                    "name": "Bukit Panjang",
                    "images": [
                        {
                            "url": "facebook.com",
                            "libraryUuid": "2222",
                            "uuid": "9999"
                        }
                    ]
                },
                "uuid": "i_8253578c-600d-4dfd-bd40-ce5b9bb89067",
                "headline": "Awesome",
                "dataset": "attractions",
                "insiderUUID": "i_c932e85b-0aee-4462-b930-962f555b64bd",
                "insiderInfo": [
                    {
                        "gender": "m",
                        "funFacts": [
                            {
                                "type": "knock knock!",
                                "answer": "Who's there?"
                            }
                        ],
                        "profileImage": "newImage.jpg",
                        "shortDescription": "Samething",
                        "fullDescription": "Whatever Description",
                        "interests": [
                            "HELLO",
                            "WORLD"
                        ],
                        "tribes": [
                            "HELLO",
                            "WORLD"
                        ],
                        "uuid": "i_c932e85b-0aee-4462-b930-962f555b64bd",
                        "personalities": [
                            "HELLO",
                            "WORLD"
                        ],
                        "travelledCities": [
                            "HELLO",
                            "WORLD"
                        ]
                    }
                ]
            }
        ],
        "count": 1
    },
    "statusCode": 200
}

Не знаю, где я ошибаюсь, поскольку пункты в ответе кажутся дублированными, но число равно 1 .

Вот код

module.exports.index = (_event, _context, callback) => {

  Recommendation.scan().exec((_err, recommendations) => {
    if (recommendations.count == 0) {
      return;
    }
    let results = [];
    recommendations.forEach((recommendation) => {
      Insider.query({uuid: recommendation.insiderUUID}).exec((_err, insider) => {
        if (insider.count == 0) {
          return;
        }
        recommendation.insiderInfo = insider;
        results.push(recommendation);
      });
    });
    const response = {
      data: {
        results: results,
        count: results.count
      },
      statusCode: 200
    };
    callback(null, response);
  });
};

1 Ответ

0 голосов
/ 08 января 2019

РЕДАКТИРОВАТЬ: Мой предыдущий код игнорировал тот факт, что ваш «инсайдерский» запрос является асинхронным. Этот новый код обрабатывает это и соответствует вашему редактированию.

const async = require('async'); // install async with 'npm install --save async'
[...]
module.exports.index = (_event, _context, callback) => {

  Recommendation.scan().exec((_err, recommendations) => {
    if (_err) {
      console.log(_err);
      return callback(_err);
    }
    if (recommendations.count == 0) {
      const response = {
        data: {
          results: [],
          count: 0
        },
        statusCode: 200
      };
      return callback(null, response);
    }

    let results = [];
    async.each(recommendations, (recommendation, cb) => { // We need to handle each recommendation asynchronously...
      Insider.query({uuid: recommendation.insiderUUID}).exec((_err, insider) => { // because this is asynchronous
        if (_err) {
          console.log(_err);
          return callback(_err);
        }
        if (insider.count == 0) {
          return cb(null);
        }
        recommendation.insiderInfo = insider;
        results.push(recommendation);
        return cb(null);
      });
    }, (err) => { // Once all items are handled, this is called
      if (err) {
        console.log(err);
        return callback(err);
      }
      const response = { // We prepare our response
        data: {
          results: results, // Results may be in a different order than in the initial `recommendations` array
          count: results.count
        },
        statusCode: 200
      };
      callback(null, response); // We call our main callback only once
    });
  });
};

Первоначальный (частично неверный) ответ, для справки.
Вы помещаете результат своего отображения в объект, который вы в настоящее время отображаете, и callback вызывается здесь несколько раз. Это довольно много неожиданного материала о поведении.
Попробуйте следующее:

let results = [];
recommendations.forEach((recommendation) => {
    Insider.query({uuid: recommendation.insiderUUID}).exec((_err, insider) => {
        if (insider.count == 0) {
          return;
        }
        recommendation.insiderInfo = insider;
        results.push(recommendation);
    });
});    
let response = {
  data: {
    results: results,
    count: results.count
  },
  statusCode: 200
};
callback(null, response);
...