分解使用某些ES5 /高级JavaScript编写方法的代码段?

时间:2019-01-12 10:11:43

标签: javascript ecmascript-5 keystonejs

有人可以解释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()
    ]);
}

3 个答案:

答案 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值的namecategory键。对我来说,这似乎是一些“模拟数据”,只是出于测试目的而放置在那里。

我转移了下一部分,因为它使代码更易于理解。

此部分:

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)

https://babeljs.io/repl

您可以使用此工具进行翻译。