【发布时间】:2018-02-09 03:07:19
【问题描述】:
这是一个有点长和凌乱的代码,但请耐心等待,因为我需要完成这个。
我正在尝试为每个用户更新一个 json 对象。我希望循环迭代等待异步过程结束以避免竞争条件。但是,这导致了回调地狱,现在我无法确定每个回调返回的正确位置。
我在 Nesting async.eachSeries 上提到了这个答案,并尝试根据它来构建我的代码。但它仍然不起作用。代码在 callback1() 处给出回调已经调用错误。
async.eachOfSeries(res, function (value, camp, callback3) {
let _id = res[camp]._id;
let arr = res[camp].campaignID;
async.eachOfSeries(arr, function2, function (err) {
callback3();
})
function function2(value1, i, callback2) {
let users = arr[i].users;
let id = arr[i].id;
let loop = Math.ceil(users / 1000);
let limit = 0,
offset = 0;
for (let j = 0; j < loop; j++) {
if (users > 1000) {
limit = 1000;
users -= limit;
} else {
limit = users;
}
console.log(limit + " limit " + offset + " offset");
var start = Date.now();
while (Date.now() < start + 100) {}
const request = mailjet
.get("messagesentstatistics")
.request({
"CampaignID": id,
"AllMessages": true,
"Limit": limit,
"Offset": offset
})
request
.then((result) => {
let data = result.body.Data;
var loop = 0;
async.eachOfSeries(data, function1, function (err) {
console.log("function");
callback2();
})
console.log("oooooo");
})
.catch((err) => {
console.log(err);
})
offset += limit;
}
function function1(value2, val, callback1) {
console.log(data +" data");
let jsonObj = data[val];
let email = jsonObj.ToEmail;
jsonObj['retailer'] = res[camp].retailer;
jsonObj['summary'] = 'f';
let tempObj = {};
tempObj[id] = jsonObj;
let options = {
new: true
};
let campId = id;
User.addCampaignResponse(email, campId, tempObj, options, function (err, results) {
if (err) {
throw err;
} else {
console.log("aasd");
Campaign.updateResponse(_id, function (err, results2) {
if (err)
throw err;
else {
console.log("asdasaadas");
callback1();
}
}) // console.log(results);
}
})
}
}
}, function (err) {
callback(undefined, "doneeeeee");
})
还有比这更好的方法吗?我也可以在某个地方使用瀑布吗?我可以更改回调位置以避免错误吗?
编辑:简化代码
function function2(value1, i, callback2) {
// ...
const request = mailjet
.get("messagesentstatistics")
.request({
// ...
});
request
.then((result) => {
// ...
async.eachOfSeries(data, function1, function (err) {
callback2();
});
})
.catch((err) => {
// ...
});
}
function function1(value2, val, callback1) {
// ...
User.addCampaignResponse(email, campId, tempObj, options, function (err, results) {
if (err) {
throw err;
} else {
Campaign.updateResponse(_id, function (err, results2) {
if (err) throw err;
else callback1();
});
}
});
}
async.eachOfSeries(res, function (value, camp, callback3) {
// ...
async.eachOfSeries(arr, function2, function (err) {
callback3();
});
},
function (err) {
callback(undefined, "doneeeeee");
});
【问题讨论】:
-
var start = Date.now(); while (Date.now() < start + 100) {}-- 好的,我只需要问一下。为什么? -
为了便于阅读,如果您使用命名函数而不是匿名函数,将会有很大帮助。
-
如果要整理,先改代码,把一些部分放到函数中,这样会更容易阅读,便于理解和调试
-
@MisterKartoot 有很多比同步阻塞线程更好的节流解决方案......
-
@GrégoryNEUT 提出了一个很好的观点,即把一些功能拉到他们自己的部分。您的代码似乎做了很多循环并且非常复杂,所以我不确定它到底做了什么。然而,我已经重写了其中的一些,以展示如何将其重组为单独的函数:这里是 gist
标签: javascript node.js asynchronous callback async.js