Javascript, how to await multiple promises
This question already has an answer here:
Your fundamental SQL functions
need to be converted to promises
in order to be awaited
.
See Async Function
, Promise
and Array.prototype.map()
for more info.
// 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)
}))
You just need to wrap the mysql callbacks into promises:
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);
});
});
}
And by the way, this is very ugly:
if (artists.length != 0) {
for (key in artists) {
Just do:
for(const artist of artists)
promises.push(someApiCall(artist));
or:
const promises = artists.map(someApiCall);
The Easy way is to use already existing ORM like sequalizejs or etc they return promise for you and instead of running find and create in separate Raw query in native MySQL driver. You can simply use API'S like find or create something.
i explain you how async works in your example , i took a piece of code from your example.
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');
})();
look into createArtist function this is exactly what you have . Three things you have to note here,
so the code can be changed to
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');
})();
Things changed here , added native promise wrapper and return it, before it goes asynchronous. called resolve to make success . And reject to make it fail.
Don't forget to add try ...catch blog for await's to handle error.
链接地址: http://www.djcxy.com/p/55536.html上一篇: 承诺如何在这种情况下实施?
下一篇: Javascript,如何等待多重承诺