Я не знаю много о KeystoneJS. Во всяком случае, вот мои два цента:
const importData = [
{ name: 'A draft post', category: 'Keystone JS' },
// ...
];
importData
- это Array
, который содержит набор Object
экземпляров, каждый из которых имеет клавиши name
и category
со значениями String
. Мне кажется, это какие-то «фиктивные данные», которые просто помещаются туда для целей тестирования.
Я переместил следующие части, потому что это делает код более понятным.
Эта часть:
const categories = {};
Мне кажется, что человек, который написал это, пытался реализовать какую-то форму "кеширования". Константа categories
является простым «контейнером» для хранения сообщений, поэтому их можно использовать позже, а не создавать заново. Функция createPost
раскрывает цель, если вы прочитаете ее.
const createPost = ({ name, category }) => {
let postCategory = new PostCategory.model({ category });
if (categories[category]) {
postCategory = categories[category];
}
categories[category] = postCategory;
const post = new Post.model({ name });
post.category = postCategory._id.toString();
return Promise.all([
post.save(),
postCategory.save()
]);
}
Кажется, что первый if
использует конструкцию "кэширования" (const category
), но то, как это происходит, немного сбивает с толку. Вот как бы я его рефакторинг:
const createPost = ({ name, category }) => {
if (!categories[category]) {
categories[category] = new PostCategory.model({ category });;
}
const post = new Post.model({ name });
post.category = categories[category]._id.toString();
return Promise.all([
post.save(),
categories[category].save()
]);
}
Наконец, для exports
части:
Модуль экспортирует function
, который ожидает обратного вызова в качестве аргумента (done
). Затем он пытается создать Promise
из всех «постов» фиктивных данных (и - насколько я понимаю - не удается), сопоставляя функцию createPost
поверх него. Причина, по которой я думаю, что это не удается, заключается в том, что Array.prototype.map
не возвращает Promise
, он возвращает новый экземпляр Array
, у которого нет метода then
(см. Следующую строку). Вместо того, чтобы звонить then
, он должен быть снова Promise.all
. Когда это окончательное Promise
успешно (или неуспешно) вызывается обратный вызов с результатом.
exports = function (done) {
const importPromise = importData.map(({ name, category }) => createPost({ name, category }));
importPromise.then(() => done()).catch(done);
};
Опять же, я бы переписал это так:
exports = function (done) {
Promise.all(importData.map(createPost)).then(done).catch(done);
};
Или просто return
окончательный Promise
и избавление от done
обратного вызова в целом.