Javascript,如何等待多重承诺
这个问题在这里已经有了答案:
您的基本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)
}))
你只需要将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);
简单的方法是使用已有的ORM(如sequalizejs等),它们会为您返回承诺,而不是在本机MySQL驱动程序中的单独原始查询中运行查找和创建操作。 你可以简单地使用API来查找或创建一些东西。
我向你解释你的例子中async是如何工作的,我从你的例子中拿了一段代码。
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');
})();
事情发生了变化,添加了本地承诺包装并在异步之前将其返回。 所谓决心取得成功。 并拒绝让它失败。
不要忘记添加try ... catch博客等待处理错误。
链接地址: http://www.djcxy.com/p/55535.html