我想要做的是:
我得到的是:
我在和Node和mysql一起工作。要插入关系,我必须等待艺术家插入或创造。我试图用以下代码来完成:
let promises = [];
if (artists.length != 0) {
for (key in artists) {
promises.push( find_artist_id_or_create_new_artist(artists[key]) )
}
}
await Promise.all(promises);返回身份证:
async function find_artist_id_or_create_new_artist(artist_name) {
return await find_artist_return_id(artist_name, create_artist_return_id)
} 寻找艺术家:
async function find_artist_return_id(artist_name, callback) {
var sql = "SELECT * FROM `artists` WHERE `name` LIKE "+con.escape(artist_name)+" LIMIT 1;"
con.query(sql, (err,row) => {
if(err) throw err;
if (row.length == 0) {
return callback(artist_name)
} else {
return row[0].id
}
});
}创造一个艺术家
async function create_artist_return_id(artist_name) {
var sql = "INSERT INTO `artists` (`id`, `name`, `meta_1`, `meta_2`) VALUES (NULL, "+con.escape(artist_name)+", NULL, NULL)";
con.query(sql, (err, result) => {
if(err) throw err;
return result.insertId
});
}我知道我不能返回一个con.query函数,但是我不知道如何正确地设置代码来完成这个任务。一个链接,或帮助如何寻找一个答案,将受到赞赏。
发布于 2018-04-03 10:24:13
您的基本SQL functions需要转换为promises才能成为awaited。
更多信息请参见Async Function、Promise和Array.prototype.map()。
// Artist Ids.
const artistIds = await Promise.all(artists.map(async (artist) => await findArtist(artist) || await createArtist(artist)))
// Find Artist.
const findArtist = artist => new Promise((resolve, reject) => con.query(`SELECT * FROM \`artists\` WHERE \`name\` LIKE ${con.escape(artist)} LIMIT 1;`, async (error, row) => {
if(error) return reject(error)
if (!row.length) return resolve(await createArtist(artist))
return resolve(row[0].id)
}))
// Create Artist.
const createArtist = artist => new Promise((resolve, reject) => con.query(`INSERT INTO \`artists\` (\`id\`, \`name\`, \`meta_1\`, \`meta_2\`) VALUES (NULL, ${con.escape(artist)}, NULL, NULL)`, (error, result) => {
if (error) return reject(error)
return resolve(result.insertId)
}))发布于 2018-04-03 10:24:41
您只需要将mysql回调包装成承诺:
function find_artist_return_id(artist_name) {
return new Promise((resolve, reject) => {
var sql = "SELECT * FROM `artists` WHERE `name` LIKE "+con.escape(artist_name)+" LIMIT 1;"
con.query(sql, (err,row) => {
if(err) return reject(err);
if (row.length == 0) {
return resolve(artist_name);
return resolve(row[0].id);
});
});
}顺便说一下,这是非常丑陋的:
if (artists.length != 0) {
for (key in artists) {只要做:
for(const artist of artists)
promises.push(someApiCall(artist));或者:
const promises = artists.map(someApiCall);发布于 2018-04-03 10:52:54
简单的方法是使用已经存在的ORM,如、sequalizejs、等,它们为您返回承诺,而不是在本地MySQL驱动程序中运行、查找和创建单独的原始查询。您可以简单地使用API,比如查找或创建一些东西。
我在您的示例中解释了异步是如何工作的,我从您的示例中获取了一段代码。
async function createArtist(artist_name) {
var sql = "INSERT INTO `artists` (`id`, `name`, `meta_1`, `meta_2`) VALUES (NULL, "+con.escape(artist_name)+", NULL, NULL)";
con.query(sql, (err, result) => {
if(err) throw err;
return result.insertId
});
}
const artistId = (async () => {
await createArtist('maxi');
})();查看createArtist函数--这正是您所拥有的。有三件事你要注意,
所以代码可以更改为
async function createArtist(artist_name) {
return new Promise((resolve,reject)=>{
var sql = "INSERT INTO `artists` (`id`, `name`, `meta_1`, `meta_2`) VALUES (NULL, "+con.escape(artist_name)+", NULL, NULL)";
con.query(sql, (err, result) => {
if(err) reject(err);
resolve(result.insertId)
});
});
}
const artistId = (async () => {
await createArtist('maxi');
})();这里发生了变化,添加了本机承诺包装器,并在它异步之前返回它。叫做决心取得成功。拒绝让它失败。
不要忘了添加尝试...catch博客,以等待处理错误。
https://stackoverflow.com/questions/49627044
复制相似问题