节点承诺链似乎在string匹配中被破坏,如何解决?

现在我一直在研究下面的代码。 我对Promises和asynchronous代码相当陌生,但是我在这里和其他地方阅读了一些非常方便的post,在创build下面的代码的过程中描述了他们。

其目的是创build一个函数来检测文章中的作家插入链接标签的文章,并正确地将其replace为另一篇具有相同名称的文章的链接(如果存在)。 在这种情况下,文本标签链接到另一篇名为articleName文章将被写为<<articleName>> – 我知道风格<<texthere>>可能会导致一些问题,但实际的标签本身可以改变。 我只是想要文本replace正确返回,所以我可以传递新的string到响应被呈现。

我对这个问题感到不知所措,在这里 – 似乎在linkedArticle通过后的某个时候,承诺链被打破了。 我在想,使用正则expression式匹配(我已经使用string.js between函数,以及相同的结果)不适用于Promise.resolve() 。 我得到的输出只是一个匹配的matchedArray的stringundefined 。 我可能是过度的returnPromise.resolve() ,我不知道。

我正在使用Node.js和Mongoose。 我玩过使用原生承诺, asyncstring.jsunderscore 。 下面的代码使用async和string.js。

我已经整理了下面的代码,尽可能在这里发布。 对于通过+吨的回报和解决(这可能是我的问题很可能是一个原因?)的长期论点道歉。 这是我正在做的事情之一,检查哪里可以打破链条; 我保留这篇文章只是为了分离一些东西,希望提高可读性。

文章模式是一个简单的介绍string入口,这是我用于testing的目的。

 //Show article var show = (req, res, next) => { let id = req.params.id; Article.findOne({_id : id}).populate('_author').then(function(article) { if (!article) return res.render('404'); return Promise.resolve(replaceTextLinks(article.introduction)).then(function(text){ console.log("Returned text is" + text) }); }); } var replaceTextLinks = (text) => { let regExp = /<<([a-zA-z0-9 ]+)>>/g; console.log("Initial passed in text is: " + text) return Promise.resolve(text.match(regExp)).then(function(matchArray){ console.log("Matched array is: " + matchArray); async.each(matchArray, function(matchText){ console.log("Matched Text is: " + matchText); return linkArticle(text, matchText); }); }).catch(function(err){ console.log("Error encountered: %s", err); }); } var linkArticle = (text, matchText) => { let regExp = /([a-zA-Z]+)/g; return Promise.resolve(matchText.match(regExp)).then(function(linkedArticle){ console.log("Linked Article is: " + linkedArticle); return Promise.resolve(matchArticle(text, matchText ,linkedArticle)); }) } var matchArticle = (text, matchText, linkedArticle) => { return Article.findOne({title:linkedArticle}).then(function(matchedArticle) { console.log("matchedArticle is: " + matchedArticle); if(matchedArticle) { return Promise.resolve(replaceTextWithArticle(text, matchText, matchedArticle, linkedArticle)); } }) } var replaceTextWithArticle = (text, matchText, matchedArticle, linkedArticle) => { console.log("Replacing initial text: " + text); replacedText = '<a href=' + '/articles/view/' + matchedArticle._id + ">" + linkedArticle + "</a>" return Promise.resolve(S(text).replaceAll(matchText, replacedText).s).then(function(newText){ console.log("Replaced text is: " + newText); return Promise.resolve(newText); }) } 

下面是我运行“show”时的控制台输出。 文章集合中的其他地方称为“ Privacy ,与传入的标签<<Privacy>>匹配。 在控制台上的LinkedArticle之后,返回的文本是未定义的,告诉我打嗝在某处,但是我可能是错的。 即使是带有三个标签的物品也是如此。

 Initial passed in text is: This article contains a tag, <<Privacy>>. Matched array is: <<Privacy>> Matched Text is: <<Privacy>> Linked Article is: Privacy Returned text is undefined matchedArticle is: { _id: 5909f3efe8d05c4e3827c4d1, title: 'Privacy', _author: 5909f3eee8d05c4e3827c4d0, category: 'Security', introduction: 'Type your article\'s introduction here...', contents: 'Type your article\'s content here...', conclusion: 'Type your article\'s conclusion here...', __v: 0, published: false } Replacing initial text: This article contains a tag, <<Privacy>>. Replaced text is: This article contains a tag, <a href=/articles/view/5909f3efe8d05c4e3827c4d1>Privacy</a>. 

非常感谢您提供的任何帮助。 我只是在承诺链似乎正在打破自己的亏损。

首先,你正在使用Promise.resolve – 事实上,你根本不需要在你的代码中使用它

其次, Promise + async.js === nothing but trouble

因此,删除所有无用的Promise.resolve ,并用Promise.allreplaceasync.each,并依靠matchArticle是唯一需要返回Promise的函数,因为.findOne显然是这样做的,您的代码可以大大简化 – 下面的代码不使用我可以添加到你的代码的所有ES6的调整,但我不希望在答案中的代码超越你的能力

 const show = (req, res, next) => { const id = req.params.id; Article.findOne({_id: id}).populate('_author').then((article) => { if (!article) { return res.render('404'); } return replaceTextLinks(article.introduction).then((text) => { console.log("Returned text is" + text) }); }); } const replaceTextLinks = (text) => Promise.all(text.match(/<<([a-zA-z0-9 ]+)>>/g).map(matchText => linkArticle(text, matchText))); const linkArticle = (text, matchText) => matchArticle(text, matchText, matchText.match(/([a-zA-Z]+)/g)); const matchArticle = (text, matchText, linkedArticle) => { return Article.findOne({title:linkedArticle}).then(function(matchedArticle) { console.log("matchedArticle is: " + matchedArticle); if(matchedArticle) { return replaceTextWithArticle(text, matchText, matchedArticle, linkedArticle); } }); }; const replaceTextWithArticle = (text, matchText, matchedArticle, linkedArticle) => { console.log("Replacing initial text: " + text); replacedText = '<a href=' + '/articles/view/' + matchedArticle._id + ">" + linkedArticle + "</a>" return S(text).replaceAll(matchText, replacedText).s; };