gpt4 book ai didi

javascript - 如何在 node.js 和 MongoDb 的 javascript 中混契约(Contract)步和异步代码

转载 作者:行者123 更新时间:2023-11-30 12:28:13 24 4
gpt4 key购买 nike

我有这段代码:

var re = new RegExp("<a href=\"(news[^?|\"]+).*?>([^<]+)</a>", "g");
var match;
while (match = re.exec(body)){
var href = match[1];
var title = match[2];
console.log(href);

db.news.findOne({ title: title }, function(err, result){
if (err) {
console.log(err);
} else {
console.log(href);
// more codes here
}
});
}

这是示例输出:

news/2015/02/20/347332.html
news/2015/02/19/347307.html
news/2015/02/19/347176.html
news/2015/02/19/347176.html
news/2015/02/19/347176.html
news/2015/02/19/347176.html

所以,我有三组数据要传递给 findOne 函数。但是,只有最后一个通过了三次。如何解决?

基于 jfriend00 和 Neta Meta 的更新,这是使其工作的两种方法:

var re = new RegExp("<a href=\"(news[^?|\"]+).*?>([^<]+)</a>", "g");
var cnt = 0;
function next(){
var match = re.exec(body);
if (match) {
var href = match[1];
var title = match[2];
db.news.findOne({ title: title }, function(err, result){
if (err) {
console.log(err);
} else {
console.log(href);
// more codes here
}
});
}
}
next();

或者

var asyncFunction = function(db, href, title){
db.news.findOne({ title: title }, function(err, result){
if (err) {
console.log(err);
} else {
console.log(href);
// more codes here
}
});
}

var re = new RegExp("<a href=\"(news[^?|\"]+).*?>([^<]+)</a>", "g");
var match;
var cnt = 0;
while (match = re.exec(body)) {
asyncFunction(db, match[1], match[2]);
}

最佳答案

您没有获得预期输出的原因是因为您正在为所有数据库调用共享 hreftitle 变量。因此,不会为每个异步数据库操作单独跟踪这些操作。

如果您可以同时执行所有异步函数并且可以按任何顺序处理数据,那么您只需要创建一个闭包,以便为每次循环调用分别捕获局部变量:

var re = new RegExp("<a href=\"(news[^?|\"]+).*?>([^<]+)</a>", "g");
var match, cntr = 0;
while (match = re.exec(body)){
(function(href, title, index) {
console.log(href);
db.news.findOne({ title: title }, function(err, result){
if (err) {
console.log(err);
} else {
console.log(href);
// more codes here
}
});
})(match[1], match[2], cntr++);
}

如果您想连续发出请求(一次只发出一个请求),那么您就不能真正使用 while 循环来控制事情,因为它会同时发出所有请求。我倾向于将这种类型的设计模式与 next() 本地函数一起使用,而不是使用 while 循环进行串行操作:

function someFunction() {

var re = new RegExp("<a href=\"(news[^?|\"]+).*?>([^<]+)</a>", "g");

function next() {
var match = re.exec(body);
if (match) {
var href = match[1];
var title = match[2];

db.news.findOne({ title: title }, function(err, result){
if (err) {
console.log(err);
} else {
console.log(href);
// more codes here

// launch the next iteration
next();
}
});
}
}

// run the first iteration
next();
}

使用 promises,您可以 promisify() db.news.findOne() 函数,以便它返回一个 promise,将所有匹配项收集到一个数组中,然后使用.reduce() 使用 promise 的 .then() 方法对所有数据库调用进行排序。

关于javascript - 如何在 node.js 和 MongoDb 的 javascript 中混契约(Contract)步和异步代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28620161/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com