如何在javascript中使用.reduce()来连接带有参数的promises /函数数组

时间:2017-07-12 18:12:34

标签: javascript node.js promise

我正在寻找使用reduce()循环返回promise的函数数组。目标是将它们链接起来,等待当前迭代在开始新迭代之前完成。

这对我来说尤其令人困惑,因为我需要传递数组索引和另一个参数。

我知道这里和谷歌有一些例子,但是对我来说这些都是抽象的解释,我无法理解它们的解释方式。

这是我的代码(编辑后现在正在运行):

@more_keys

下面是每个arrayOfFunctions数组中的函数。它使用上面代码中的posts.map()传递给它。我认为使用.map()可以正确地完成它。

getAllPostsInfo(maxNumberOfPosts)

.then((posts) => {                                                                      
    printIntroMsg(posts)
    var arrayOfFunctions = posts.map( () => {
        return main
    })

    arrayOfFunctions.reduce((p, fn, i) => {
    return p.then( () => {

        // you may customize what you pass to the next function in the chain
        // and you may accumulate prior results in some other data structure here
        return fn(posts, i);
    });
    }, Promise.resolve() )
        .then(result => {
            // all done here
        }).catch(err => {
            // error here
        });
})

1 个答案:

答案 0 :(得分:3)

这个问题很难遵循,而且代码似乎包含许多错误,因此很难从中找出答案。

但是,如果我回到你的简短描述,听起来你可能希望按顺序执行一系列函数(每个函数都返回一个promise),等待一个函数在开始下一个之前完成并且你似乎想用.reduce()来做那个。如果是这样,那么你可以这样做:

let arrayOfFunctions = [...];

arrayOfFunctions.reduce((p, fn, index) => {
    return p.then(val => {
        // you may customize what you pass to the next function in the chain
        // and you may accumulate prior results in some other data structure here
        return fn(val);
    });
}, Promise.resolve()).then(result => {
    // all done here
}).catch(err => {
    // error here
});

此代码将前一个promise的解析结果传递给数组中的下一个函数。你可以明显地适应你想要的。像这样的.reduce()链的解析结果是最后一个承诺的解析结果。如果要累积所有操作的结果,则通常会将对象传递给每次将解析结果添加到该对象的每个函数,或者创建一个存储结果的副变量(如数组)。 / p>

回答你的进一步问题:

  

什么是Promise.resolve()

这本身就创造了一个解决的承诺。我们正在使用.reduce()创建一系列承诺,如x.then().then().then().then()中所示。要做到这一点,我们需要承诺从链条开始。我们使用Promise.resolve()来启动链。所以,它本质上是Promise.resolve().then().then().then()在每个.then()处理程序中,我们执行数组中的下一个函数并返回它的promise(从而将它添加到链中)。

  

什么是val

val是链中先前承诺的已解析值。它最初为undefined,因为第一个承诺是Promise.resolve(),它没有解析的值。在那之后,它将是返回promise所解决的每个函数。你要求的.reduce()方案,有助于将第一个结果传递给第二个函数,第二个结果传递给第三个函数,依此类推。

  

我在哪里放置函数所需的参数(posts,i)?

return fn(val)是调用函数数组中函数的位置。如果他们需要论证,那就是你把它们放在哪里。您的问题询问了一系列函数,并没有描述这些函数需要哪些参数(我无法很好地理解您的代码以便理解它)。如果您需要进一步的帮助,那么请更详细地描述您需要传递给您开始使用的函数数组中的每个函数的参数。

好吧,也许我终于明白你要做的事了。这是我对你要做的事情的看法。

  1. 您想致电getAllPostsInfo()以获取帖子列表。
  2. 然后,您想致电printInfoMsg(posts)
  3. 然后,您想在每个帖子上致电findAndInsertLinksToPosts()然后findAndInsertImgsIntoPostsContentandThunbnail()
  4. 并且,您希望序列化这些操作,以便您在一个帖子上操作,并且只在前一个帖子完成后开始(我不确定您为什么会有这个限制)
  5. 如果是这样的话,那就是我的建议:

    getAllPostsInfo(maxNumberOfPosts).then(posts => {
        // I'm assuming this is not asycnhronous
        printIntroMsg(posts);
    
        // now serially process each post
        posts.reduce((promise, post, i) => {
            return promise.then(() => {
                return findAndInsertLinksToPosts(post, posts, i).then(() => {
                    return findAndInsertImgsIntoPostContentandThumnail(post, posts, i);
                });
            });
        }, Promise.resolve());
    }).then(() => {
        // all done here
    }).catch(err => {
        // error here
    });