我正在尝试在nodejs中编写一个cron函数,它从db中获取所有用户的user_id,然后我想解析每个user_id。
这是我的代码:
cron.schedule('43 11 * * *', function(){
var now = moment()
var formatted = now.format('YYYY-MM-DD HH:mm:ss')
console.log('Starting the cron boss!');
var dbSelectPromise = function(db, sql1) {
return new Promise(function(resolve, reject) {
db.select(sql1, function(err, data) {
if (err) {
reject(err)
} else {
resolve(data)
}
})
})
}
var users =[]
var sql = "select distinct(user_id) from user_level_task"
dbSelectPromise(db,sql).then(function(secondResult){
for(i=0;i<secondResult.length;i++){
var sql1 = "select max(level_id) as level from user_level_task where user_id ="+secondResult[i].user_id
dbSelectPromise(db,sql1).then(function(thirdResult){
console.log(thirdResult)
console.log(current)
var sql2 = "select task_id form user_level_task where user_id = '"+secondResult[i].user_id+"' and level_id = '"+thirdResult[0].level+"' "
dbSelectPromise(db,sql2).then(function(fourthResult){
var leng = fourthResult.length
for(i=0;i<leng;i++){
console.log(fourthResult[i])
}
})
})
}
})
});
我面临的问题是我无法在第三和第四次承诺中获得i的价值。请帮忙!
答案 0 :(得分:0)
我认为发生的事情是i
在创建新的承诺时不再相同,因为for循环仍然在运行。看来您真正需要的是user_id
和level_id
。我建议你稍微重构你的代码以减少嵌套并传递你未来承诺所需的值。
也许类似于此:
dbSelectPromise(db, sql)
.then(secondResult => {
const levelPromises = [];
secondResult.forEach(res => {
levelPromises.push(getLevelByUserId(res.user_id, db));
});
return Promise.all(levelPromises); // Promise.all only if you want to handle all success cases
})
.then(result => {
result.forEach( level => {
{ userId, queryResult } = level;
// ...
})
//...
})
.catch(err => {
console.log(err);
});
function getLevelByUserId(userId, db) {
const query = `select max(level_id) as level from user_level_task where user_id = ${userId}`;
return dbselectPromise(db, query).then(result => { userId, result });
}
它创建一个包含所有获取级别查询的数组作为promises,然后使用Promise.all()
将其传递到下一步,只有在所有查询都成功时才会解析。此时,您将再次访问每个结果的userId,因为我们在新函数中将其返回给您的下一组查询。
我认为你应该进一步抽象你的查询而不是使用通用dbSelectPromise
而不要忘记catch()
,否则你不会知道&#39发生了。
注意:它假定您的db
变量已正确实例化,并且您的原始db.select
不需要根据您正在使用的库返回。那里还有一些新的语法。
答案 1 :(得分:0)
我面临的问题是我无法在第三和第四次承诺中获得i的价值。请帮忙!
这是因为您在不使用i
的情况下使用let
重新初始化。当循环进行时,该值将与您期望的值不同。
每个承诺都依赖于另一个并且需要同步运行
为了实现这一点,你需要链接承诺。此外,您可以使用Promise.all()
一次执行一连串的承诺。请记住,Promise.all()是全有或全无。
对代码进行这些更改后,我得到以下结构。
'use strict';
let _ = require('lodash');
function dbSelectPromise(db, sql1) {
return new Promise((resolve, reject) => {
return db.select(sql1, (err, data) => {
if (err) {
return reject(err);
}
return resolve(data);
});
});
}
function process(secondResult) {
let sql1 = "select max(level_id) as level from user_level_task where user_id =" + secondResult[i].user_id;
return dbSelectPromise(db, sql1).then(function (thirdResult) {
console.log(thirdResult);
let sql2 = "select task_id form user_level_task where user_id = '" + secondResult[i].user_id + "' and level_id = '" + thirdResult[0].level + "' ";
return dbSelectPromise(db, sql2);
});
}
function getUsers() {
let sql = "select distinct(user_id) from user_level_task";
return dbSelectPromise(db, sql).then((users) => {
return users;
}).catch(() => {
return [];
});
}
cron.schedule('43 11 * * *', function () {
var now = moment();
var formatted = now.format('YYYY-MM-DD HH:mm:ss');
getUsers().then((users) => {
let batches = _.map(users, function (user) {
return process(user);
});
return Promise.all(batches);
}).then((fourthResult) => {
console.log('Your fourthResult [[],..]', fourthResult);
}).catch(() => {
console.log('err while processing', err);
});
});