【问题标题】:Cannot get nested promises to return value to next promise chain无法获得嵌套承诺以将值返回到下一个承诺链
【发布时间】:2017-07-21 06:08:01
【问题描述】:

在下面,您将看到我在注释代码中遇到的问题。我有一个嵌套的承诺,它在集合中创建一个对象,然后返回它。

但是,我认为我遇到了异步问题。该函数在嵌套的 Promise 返回创建的对象之前完成。

我仍在掌握 Promise 链接,我可能在这里做错了很多。如果我可以清理/弄平其中的一些,其中大部分可能会被清除。

 PostSchema.statics.createPost = function (o, user) {
    var whiskey;
    return Whiskey
        .createWhiskey(o.whiskey.value)
        .then(function (whiskeyData) {
            whiskey = whiskeyData.whiskey;
            o.post.whiskey = whiskeyData.whiskey._id;

            if (whiskeyData.whiskey.distiller) {
                o.post.distiller = whiskeyData.whiskey.distiller;
            }

            return o.distiller.new === true && !whiskey.distiller ? Distiller.newDistiller(o.distiller.value) : Promise.resolve()
                .then(function (distiller) {
                    //this never invokes   <---- it's called from the function below
                    console.log('never invokes', distiller).
                    if (distiller) {
                        whiskey.distiller = distiller._id;
                        //test this save
                        whiskey.save();
                        o.post.distiller = distiller._id;
                    }

                    var post = o.post;
                    post.user = user._id;
                    return Post
                        .createAsync(post)
                        .then(function (data) {
                            return Post
                                .populate(data, {
                                    path: 'user whiskey',
                                    populate: {
                                        path: 'distiller style',
                                    }
                                })
                        })

                        .then(function (populatedData) {
                            return (user.shareFB ? social.checkFB(user, populatedData) : Promise.resolve())
                                .then(function (FBres) {
                                    return (user.shareTWT ? social.checkTWT(user, populatedData) : Promise.resolve())
                                        .then(function (TWTres) {
                                            var socialData = [TWTres, FBres];
                                            return {
                                                'post': populatedData,
                                                'social': socialData
                                            };
                                        })
                                })
                        })
                })
        })
        .catch(function (err) {
            console.log('post create err : ', err);
        })
};

这是创建蒸馏器并尝试返回的位置:

DistillerSchema.statics.newDistiller = function (o) {

    return Distiller
        .findAsync({
            'name': o.name
        })
        .then(function (distiller) {
            if (distiller.length) {
                return distiller[0];
            }
            return Distiller
            .createAsync(o)
            .then(function (data) {
                //console.log here indicates that is is created <-- created and returned here
                console.log('distiller created ', data)
                return data;
            })
        })
        .catch(function(err) {
            console.log('create distiller err ', err);
        })
};

【问题讨论】:

  • 如果你的代码嵌套了 9 层,那么你已经可以断定你没有以正确的方式使用 Promise。不要筑巢。链。
  • Promise.resolve() 将 undefined 传递给链中的下一个函数。如果未定义威士忌数据,function (whiskeyData) { whiskey = whiskeyData.whiskey; 将中断,将直接跳至捕获
  • 是的,我应该删除那个三元组。威士忌是必填字段。
  • 您能否更新您的问题以删除三元?
  • 确定。已删除。

标签: javascript node.js mongoose promise bluebird


【解决方案1】:

听起来像是一个分组错误。而不是

return o.distiller.new === true && !whiskey.distiller
  ? Distiller.newDistiller(o.distiller.value)
  : Promise.resolve().then(…) // callback only called when no new distiller

你想要的

return (o.distiller.new && !whiskey.distiller
  ? Distiller.newDistiller(o.distiller.value)
  : Promise.resolve()
).then(…) // callback always called

至少所有其他条件句是这样的:-)

我仍在掌握承诺链

在了解到您总是需要从异步函数中return(您做得很好)之后,您应该看看how it is possible to flatten a chain(当所有条件都是局部表达式时,它适用于您的代码,而不是早期回报)。另外我建议不要缩进链接的方法调用,因为嵌套then 回调时很快就会失控,但这只是我个人的偏好。

【讨论】:

  • 谢谢@Bergi。不敢相信我错过了。感谢承诺的指导!
猜你喜欢
  • 2015-06-05
  • 2019-05-10
  • 2015-11-27
  • 1970-01-01
  • 2023-01-27
  • 2017-11-24
  • 1970-01-01
  • 2018-02-15
  • 1970-01-01
相关资源
最近更新 更多