承诺链中的返回值没有被调用

Posted

技术标签:

【中文标题】承诺链中的返回值没有被调用【英文标题】:return value inside promise chain isn't getting called 【发布时间】:2016-01-04 01:39:38 【问题描述】:

我正在使用 Promise 库 Bluebird,我目前遇到的问题是函数内部的所有内容都运行良好,但是当我尝试返回一个值时,该函数反而返回 undefined

这是承诺链:

function foo() 
    createGroupMembers(parsedChat).then(function(val) 
        var members = val;

        createMessages(parsedChat, maxPages).then(function(val) 
            var messages = val;

            Promise.all([ createFrontCover(subject, firstdateOfMessages, lastDateOfMessages, isPreview), createStats(parsedChat), createBackCover(parsedChat)])
            .then(function (results) 
                var front = results[0];
                var stats = results[1];
                var backcover = results[2];

                var book = head + front + stats + members + messages + backcover;

                console.log('pages in this book: ', pages);
                console.log(book); // logs perfect values.

                return book; 
            ); 

       );

    );

问题很简单:当调用foo()时,它的值变成undefined而不是book。为什么我会遇到这种行为?

【问题讨论】:

foo 根本不返回任何东西 我对 Bluebird 不熟悉,但我使用过原生 JS 承诺。话虽如此......匿名函数function(results)返回书。它上面的两个匿名函数function(val) 什么都不返回。 foo,到最后什么都没回。 您需要返回所有嵌套函数。 createGroupMembers、createMessages 等 @JaromandaX 我怎样才能让它返回任何东西,为什么它不返回? 【参考方案1】:
function foo() 
    return createGroupMembers(parsedChat).then(function(val) 
        var members = val;

        return createMessages(parsedChat, maxPages).then(function(val) 
            var messages = val;

            return Promise.all([createFrontCover(subject, firstdateOfMessages, lastDateOfMessages, isPreview), createStats(parsedChat), createBackCover(parsedChat)])
                .then(function(results) 
                    var front = results[0];
                    var stats = results[1];
                    var backcover = results[2];

                    var book = head + front + stats + members + messages + backcover;

                    console.log('pages in this book: ', pages);
                    console.log(book); // logs perfect values.

                    return book;
                );

        );

    );

现在 foo 将返回一个可以解析为 book 值的承诺

foo().then(function(book) 
    console.log('huzzah I have book ' + book);
);

说实话,foo 可以重写,但这完全是一个不同的问题

仅供参考:你可以为 foo 做这样的事情

function foo() 
    return createGroupMembers(parsedChat)
    .then(function(members)  // members
        return Promise.all([members, createMessages(parsedChat, maxPages)]);
    )
    .then(function(members_messages)   // membersMessages
        return Promise.all([createFrontCover(subject, firstdateOfMessages, lastDateOfMessages, isPreview), createStats(parsedChat)].concat(members_messages, [createBackCover(parsedChat)]));
    )
    .then(function(results)  // front, stats, members, messages, back
        var book = head + results.join('');

        console.log('pages in this book: ', pages);
        console.log(book); // logs perfect values.

        return book;
    );

在第二个(是你唯一的)Promise.all 中弄乱了顺序,并在其中添加了以前的 Promise 结果以使部分的最终连接变得像.join 一样简单 - 这样做也会传播任何错误都正确,所以你对 foo 的使用可以是

foo().then(function(book) 
    console.log('huzzah I have book ' + book);
).catch(function(err) 
    // handle any and all errors here
);

【讨论】:

以上是关于承诺链中的返回值没有被调用的主要内容,如果未能解决你的问题,请参考以下文章

返回承诺链中的引用数据

在使用 Redux-Thunk 异步操作的 Promise 链中使用 setInterval

我的返回值函数失败 - 我认为与承诺相关

使用GetInvocationList对委托链进行更多的控制

.sink 没有从 Future Publisher 返回承诺值

如何将承诺的返回值分配给变量? [复制]