私が達成したいこと:
私が得たもの:
私は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);
IDを返す:
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関数で返すことができないことを理解していますが、これを行うためにコードを適切に設定する方法はわかりません。回答へのリンク、または回答の検索方法のヘルプは、高く評価されています。
基本的な_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コールバックをpromiseにラップするだけです。
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ドライバーの個別のRawクエリ。検索や何かの作成などの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関数を調べてくださいこれはまさにあなたが持っているものです。ここで注意しなければならない3つの点は、
コードを次のように変更できます
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');
})();
状況がここで変更され、非同期になる前にネイティブのpromiseラッパーが追加されて返されます。成功するために解決と呼ばれます。そして、それを失敗させることを拒否します。
エラーを処理するために、try ... catchブログを追加することを忘れないでください。