有人可以解释exports
部分中的内容吗,我似乎迷失了一段时间。从importPromise
开始。似乎发生了很多事情,例如箭头功能和map方法。我看不到数据从哪里流到哪里。
const keystone = require('keystone');
const PostCategory = keystone.list('PostCategory');
const Post = keystone.list('Post');
const importData = [
{ name: 'A draft post', category: 'Keystone JS' },
...
];
exports = function (done) {
const importPromise = importData.map(({ name, category }) => createPost({ name, category }));
importPromise.then(() => done()).catch(done);
};
const categories = {};
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()
]);
}
答案 0 :(得分:0)
涉及到一些ES6魔术:)
const importPromise = importData.map(({ name, category }) => createPost({ name, category }));
importdata是一个数组。数组上的map函数要做的是获取数组的每个项目并对其应用一个函数,然后返回一个新数组,其中包含原始数组中所有已修改的项目。 map function
在ES6中,最好使用fat arrow function,即.map(function(item) { ... }
.map((item) => ...
。
魔术的第三位叫做destructuring assignment。在这种情况下,它要做的是获取一个对象,并将obj.name和obj.category分配给两个新的变量name和category。我们可以在函数中使用这些变量,就好像我们使用两个单独的参数调用了函数一样。
现在请记住,我们的map函数要求我们编写一个函数,该函数将数组项作为参数,并返回修改后的项。因此,我们最终得到的是一个映射函数,该函数循环遍历importData的参数,获取每个项目的名称和类别,并使用它们调用另一个函数createPost。 createPost的结果是该项目的新值,并且所有结果都被附加到与旧大小相同的数组中,并带有已修改的项目。
importPromise.then(() => done()).catch(done);
createPost从每个项目创建一个承诺。您可以阅读有关Promise here的更多信息。 Promise上的.then方法以函数为参数;当承诺返回时(成功或错误)被调用。 () => done()
只是使用粗箭头语法的函数,不带任何参数,而是调用done
函数。 .catch
也接受一个函数(done
是一个函数),并在promise返回错误时执行。注意这样,成功和错误都将调用完函数!
-不,此代码将无法工作,因为我们在importPromise的第一行中创建的实际上不是一个Promise,而是一个Promise数组!
祝您阅读愉快,正如Beri所建议的那样,将代码转换为es5还是值得的。
答案 1 :(得分:0)
我对KeystoneJS不太了解。无论如何,这是我的两分钱。
await asyncio.sleep(1)
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
回调。
答案 2 :(得分:-2)
您可以使用此工具进行翻译。