分解一段使用了一些ES5/高级JavaScript写法的代码段?
Break down a code segment that uses some ES5 / advanced JavaScript methods of writing?
谁能解释一下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()
]);
}
您可以使用此工具进行翻译。
涉及相当多的 ES6 魔法:)
const importPromise = importData.map(({ name, category }) => createPost({ name, category }));
importdata 是一个数组。数组上的 map 函数所做的是获取数组的每个项目并对其应用一个函数,然后 return 一个包含原始数组中所有项目但经过修改的新数组。 map function
而不是写 .map(function(item) { ... }
在 ES6 中写这个的首选方式是使用 fat arrow function,即 .map((item) => ...
魔法的第三位叫做destructuring assignment。它所做的是在这种情况下获取一个对象,并将 obj.name 和 obj.category 分配给两个新变量名称和类别。我们可以在我们的函数中使用这些变量,就像我们用两个单独的参数调用函数一样。
现在记住我们的 map 函数指示我们编写一个函数,该函数将数组项作为参数,returns 修改后的项。所以我们最终得到的是一个映射函数,它循环遍历 importData 的参数,获取每个项目的名称和类别,并用它们调用另一个函数 createPost。 createPost 的结果是项目的新值,它全部附加到一个与旧值相同大小的数组,以及修改后的项目。
importPromise.then(() => done()).catch(done);
createPost 从每个项目中创建一个承诺。您可以阅读有关 Promise here 的更多信息。 Promise 上的 .then 方法将函数作为参数;在 promise returns 时调用(成功或错误)。 () => done()
只是粗箭头语法中的一个函数,它不带参数并调用 done
函数。 .catch
也接受一个函数(done
是一个函数),并在承诺 return 出错时执行。注意。这样 done 函数在成功和错误时都会被调用!
——不,这段代码不会工作,因为我们在第一行用 importPromise 创建的实际上不是一个承诺,而是一个承诺数组!
祝你阅读顺利,正如 Beri 所建议的那样,将代码翻译成 es5 可能值得继续阅读。
我对 KeystoneJS 了解不多。无论如何,这是我的两分钱:
const importData = [
{ name: 'A draft post', category: 'Keystone JS' },
// ...
];
importData
是一个 Array
,它包含一堆 Object
个实例,每个实例都有一个 name
和 category
键以及 String
值。对我来说,这似乎是一些 "mock data",只是为了测试目的而放在那里。
我移动了下一部分,因为它使代码更易于理解。
这部分:
const categories = {};
在我看来,编写它的人试图实现某种形式的 "caching"。 categories
常量仅仅是 "container" 用于存储帖子,以便以后可以重复使用它们而不是重新创建。如果您通读 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
似乎是为了利用 "caching" 构造 (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
)。然后,它尝试通过在其上映射 createPost
函数,从模拟数据的所有 "posts" 创建一个 Promise
(并且 - 据我所知 - 失败)。我认为它失败的原因是因为 Array.prototype.map
没有 return Promise
,它 return 是一个新的 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
回调。
谁能解释一下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()
]);
}
您可以使用此工具进行翻译。
涉及相当多的 ES6 魔法:)
const importPromise = importData.map(({ name, category }) => createPost({ name, category }));
importdata 是一个数组。数组上的 map 函数所做的是获取数组的每个项目并对其应用一个函数,然后 return 一个包含原始数组中所有项目但经过修改的新数组。 map function
而不是写 .map(function(item) { ... }
在 ES6 中写这个的首选方式是使用 fat arrow function,即 .map((item) => ...
魔法的第三位叫做destructuring assignment。它所做的是在这种情况下获取一个对象,并将 obj.name 和 obj.category 分配给两个新变量名称和类别。我们可以在我们的函数中使用这些变量,就像我们用两个单独的参数调用函数一样。
现在记住我们的 map 函数指示我们编写一个函数,该函数将数组项作为参数,returns 修改后的项。所以我们最终得到的是一个映射函数,它循环遍历 importData 的参数,获取每个项目的名称和类别,并用它们调用另一个函数 createPost。 createPost 的结果是项目的新值,它全部附加到一个与旧值相同大小的数组,以及修改后的项目。
importPromise.then(() => done()).catch(done);
createPost 从每个项目中创建一个承诺。您可以阅读有关 Promise here 的更多信息。 Promise 上的 .then 方法将函数作为参数;在 promise returns 时调用(成功或错误)。 () => done()
只是粗箭头语法中的一个函数,它不带参数并调用 done
函数。 .catch
也接受一个函数(done
是一个函数),并在承诺 return 出错时执行。注意。这样 done 函数在成功和错误时都会被调用!
——不,这段代码不会工作,因为我们在第一行用 importPromise 创建的实际上不是一个承诺,而是一个承诺数组!
祝你阅读顺利,正如 Beri 所建议的那样,将代码翻译成 es5 可能值得继续阅读。
我对 KeystoneJS 了解不多。无论如何,这是我的两分钱:
const importData = [
{ name: 'A draft post', category: 'Keystone JS' },
// ...
];
importData
是一个 Array
,它包含一堆 Object
个实例,每个实例都有一个 name
和 category
键以及 String
值。对我来说,这似乎是一些 "mock data",只是为了测试目的而放在那里。
我移动了下一部分,因为它使代码更易于理解。
这部分:
const categories = {};
在我看来,编写它的人试图实现某种形式的 "caching"。 categories
常量仅仅是 "container" 用于存储帖子,以便以后可以重复使用它们而不是重新创建。如果您通读 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
似乎是为了利用 "caching" 构造 (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
)。然后,它尝试通过在其上映射 createPost
函数,从模拟数据的所有 "posts" 创建一个 Promise
(并且 - 据我所知 - 失败)。我认为它失败的原因是因为 Array.prototype.map
没有 return Promise
,它 return 是一个新的 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
回调。