Was ich erreichen möchte:
Was ich bekam:
Ich arbeite mit Node und MySQL. Um die Beziehungen einzufügen, muss ich warten, bis die Künstler eingefügt oder erstellt werden. Ich versuche mit folgendem Code zu erreichen:
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);
Rückgabe einer ID:
async function find_artist_id_or_create_new_artist(artist_name) {
return await find_artist_return_id(artist_name, create_artist_return_id)
}
Einen Künstler finden:
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
}
});
}
Einen Künstler erstellen
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
});
}
Ich verstehe, dass ich nicht in einer con.query-Funktion zurückkehren kann, aber ich kann nicht den Code richtig einrichten, um dies zu erreichen. Ein Link zu oder eine Hilfe bei der Suche nach einer Antwort wird gebeten.
Ihr SQL functions
muss in promises
konvertiert werden, um awaited
zu sein.
Siehe Async Function
, Promise
und Array.prototype.map()
für weitere Informationen.
// 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)
}))
Sie müssen nur die mysql-Callbacks in Versprechungen einschließen:
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);
});
});
}
Und das ist übrigens sehr hässlich:
if (artists.length != 0) {
for (key in artists) {
Mach einfach:
for(const artist of artists)
promises.Push(someApiCall(artist));
oder:
const promises = artists.map(someApiCall);
Der einfache Weg ist die Verwendung bereits vorhandenerORMlike sequalizejs oder etc. Sie geben ein Versprechen für Sie ab und führen stattdessen find und create in einer separaten Raw-Abfrage im nativen MySQL-Treiber aus. Sie können APIs einfach wie Suchen oder Erstellen von etwas verwenden.
ich erkläre Ihnen, wie Async in Ihrem Beispiel funktioniert. Ich habe einen Code aus Ihrem Beispiel genommen.
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');
})();
schaue in createArtist function das ist genau das, was du hast. Drei Dinge, die Sie hier beachten müssen,
so kann der Code in geändert werden
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');
})();
Hier haben sich die Dinge geändert, ein nativer Versprecher hinzugefügt und zurückgegeben, bevor er asynchron läuft. Entschlossenheit genannt, um Erfolg zu haben. Und lehne es ab, um es zum Scheitern zu bringen.
Vergiss nicht, try ... catch blog hinzuzufügen, um den Fehler zu behandeln.