我知道这是一个有很多信息的话题,但我仍然无法解决这个问题。
我正在使用连接到mysql服务器的NodeJs,我有一个数组,我需要迭代数组并对数据做一些事情,事情是我需要对mysql服务器进行查询但我需要到for循环等到我得到了查询的结果,我已经尝试了很多东西,现在我正在尝试使用bluebird的.each方法,但仍然无法正常工作,这是我的代码。
初始函数是Notification.getByUser
提前致谢
'use strict';
var Promise = require("bluebird");
module.exports = function(Notifications) {
Notifications.execute = function(sql, itemId) {
return new Promise((resolve, reject) => {
this.dataSource.connector.execute(sql, (e, result) => {
console.log('-----RESULT----', itemId);
console.log(result);
console.log('-----ERROR-----', itemId);
console.log(e);
if (result.length === 0) {
resolve(false);
} else {
resolve(true);
}
});
});
};
Notifications.isMatching = function(item, user, type) {
return new Promise((resolve, reject) => {
console.log(type, item, user);
if (item !== null) {
if (item !== user) {
resolve(false);
}
}
resolve(true);
});
};
Notifications.getByUser = function(userId, isZolver, countryId, cityId, userState, cb) {
var where = { status: 1 };
var plainText = '';
var items = Notifications.find({ where });
Promise.each(items, item => {
return Notifications.isMatching(item.isZolver, isZolver, 'isZolver')
.then(() => {
Notifications.isMatching(item.cityId, cityId, 'cityId');
})
.then(() => {
if(item.extraCondition !== null && item.extraCondition !== '') {
var sql = item.extraCondition.replace(/:user_id/g, userId);
// console.log(sql);
Notifications.execute(sql, item.id)
.then(render => console.log('extraCondition', render));
} else {
console.log('extraCondition', true);
}
});
}).then(res => {
// console.log('res del loop', res);
});
cb(null, 'ok');
};
};
答案 0 :(得分:0)
您的代码存在以下问题:
为了实现承诺链接,您必须确保返回在then
回调中创建的承诺
您不需要为可立即获得的结果创建承诺(isMatching
)
当承诺履行时,始终执行then
回调。您是否resolve(false)
无关紧要:即使承诺的值为false
,这仍然会使承诺得到满足并触发then
回调。
您的代码中有一些未知数,例如Notifications.find
,以及您正在执行的SQL类型:它是否返回结果集,如果是,您是否有兴趣获得该结果而不仅仅是解析一个布尔值?
无论如何,这里有一些应用的更正:
'use strict';
var Promise = require("bluebird");
module.exports = function(Notifications) {
Notifications.execute = function(sql, itemId) {
return new Promise((resolve, reject) => {
this.dataSource.connector.execute(sql, (e, result) => {
console.log('-----RESULT----', itemId);
console.log(result);
console.log('-----ERROR-----', itemId);
console.log(e);
resolve (result.length !== 0); // The `if ... else` is overkill
});
});
};
//You don't need isMatching to return a promise
Notifications.isMatching = function(a, b) {
return a === null || a === b;
};
Notifications.getByUser = function(userId, isZolver, countryId, cityId, userState) {
var where = { status: 1 };
var items = Notifications.find({ where })
// use filter() to limit the items to those you want to execute the SQL for
.filter(item => {
return Notifications.isMatching(item.isZolver, isZolver)
&& Notifications.isMatching(item.cityId, cityId)
&& item.extraCondition !== ''
});
// Return the promise! (don't go back to the old callback system!)
return Promise.each(items, item => {
var sql = item.extraCondition.replace(/:user_id/g, userId);
// Return the promise!
return Notifications.execute(sql, item.id);
}).then(res => {
console.log('res del loop', res);
});
};
};
请注意Notifications.getByUser
的签名没有最终的回调参数:一旦你开始使用它们就应该继续使用promises,所以当你调用这个函数时,像你一样调用结果的then
方法会做任何承诺:
Notifications.getByUser( .......arguments....).then( function () {
// do something...
});