我使用Express进行路由,使用Sequelize进行数据库管理。
app.get('/api/users/:username', (req, res) => {
let username = req.params.username;
findChattersPerRole()
.then(chattersPerRole => {
console.log('instakbot should\'ve been added by now...');
});
});
函数findChattersPerRole返回一个对象,每个用户的用户名和角色作为另一个对象。
const findChattersPerRole = () => {
return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
.then(parseJSON)
.then(r => {
let chatters = r.chatters;
let chattersPerRole = Object.keys(chatters).map(role => {
return chatters[role].map(username => {
console.log('findOrCreateViewer will be executed after this');
findOrCreateViewer(username, role);
return {
username: username,
role: role
};
});
});
return Promise.resolve(flattenDeep(chattersPerRole));
}).catch(err => {
console.log(`Error in fetch: ${err}`);
});
};
问题是,在我的路线中,我希望在我的观众插入数据库之后执行console.log('instakbot should\'ve been added by now...');
,因为在我的函数findChattersPerRole中我已经使用函数findOrCreateViewer插入它们。我希望这会发生,因为在我的路线中,当findChattersPerRole()被解析时,我编写了console.log ...
const findOrCreateViewer = (username, role) => {
return Viewer.findOrCreate({
where: {
username
},
defaults: {
instakluiten: 5,
role
}
}).spread((unit, created) => {
console.log('unit is: ', unit.dataValues.username);
if(created){
return `created is ${created}`;
}else{
return unit;
}
});
};
然而,在我的终端中你可以看到这不是它发生的方式......为什么我的承诺没有在预期的时间执行? Screenshot of my terminal
答案 0 :(得分:2)
调用函数后立即return {username: ...}
发生findOrCreateViewer(username, role);
,插入任何数据之前发生。这也意味着return Promise.resolve(flattenDeep(chattersPerRole));
在插入任何数据之前发生等等。
你说findOrCreateViewer
会返回一个承诺,所以你需要等到该承诺得到解决(即等到数据插入之后),然后再继续其他内容。
您希望chattersPerRole
成为(数组)承诺的数组,并且只有在所有承诺得到解决后才能继续。
Promise.all
很容易做到:
const findChattersPerRole = () => {
return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
.then(parseJSON)
.then(r => {
let chatters = r.chatters;
let chattersPerRole = Object.keys(chatters).map(
role => chatters[role].map(username => {
console.log('findOrCreateViewer will be executed after this');
return findOrCreateViewer(username, role).then(
() => ({username, role})
);
});
);
return Promise.all(flattenDeep(chattersPerRole));
}).catch(err => {
console.log(`Error in fetch: ${err}`);
});
};
现在findChattersPerRole
返回的承诺将在解决findOrCreateViewer
返回的所有承诺后解析。
答案 1 :(得分:2)
承诺没有魔力。返回一个承诺并不意味着调用该函数将阻止,而是您可以轻松链接回调以对结果执行某些操作。您需要使用
function findChattersPerRole() {
return fetch('https://tmi.twitch.tv/group/user/instak/chatters')
.then(parseJSON)
.then(r => {
let chatters = r.chatters;
let chattersPerRole = Object.keys(chatters).map(role => {
return chatters[role].map(username => {
console.log('findOrCreateViewer will be executed after this');
return findOrCreateViewer(username, role).then(() => {
// ^^^^^^ ^^^^^
return {
username: username,
role: role
};
});
});
});
return Promise.all(flattenDeep(chattersPerRole));
// ^^^ get a promise for an array of results from an array of promises
}).catch(err => {
console.log(`Error in fetch: ${err}`);
});
}