首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Javascript,如何等待多个承诺

Javascript,如何等待多个承诺
EN

Stack Overflow用户
提问于 2018-04-03 09:48:57
回答 3查看 11.7K关注 0票数 15

我想要做的是:

  • 收集艺术家id`s‘s
    • 要么在数据库中找到它们
    • 或者创造它们

  • 在db中创建事件,获取event_id
  • 等待两人都完成,艺术家和活动偶像聚集在一起
  • 现在循环在艺术家身上,事件组合

我得到的是:

我在和Node和mysql一起工作。要插入关系,我必须等待艺术家插入或创造。我试图用以下代码来完成:

代码语言:javascript
运行
复制
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);

返回身份证:

代码语言:javascript
运行
复制
async function find_artist_id_or_create_new_artist(artist_name) {
    return await find_artist_return_id(artist_name, create_artist_return_id)
} 

寻找艺术家:

代码语言:javascript
运行
复制
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
      }
    });
}

创造一个艺术家

代码语言:javascript
运行
复制
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函数,但是我不知道如何正确地设置代码来完成这个任务。一个链接,或帮助如何寻找一个答案,将受到赞赏。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-04-03 10:24:13

您的基本SQL functions需要转换为promises才能成为awaited

更多信息请参见Async FunctionPromiseArray.prototype.map()

代码语言:javascript
运行
复制
// 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)
}))
票数 11
EN

Stack Overflow用户

发布于 2018-04-03 10:24:41

您只需要将mysql回调包装成承诺:

代码语言:javascript
运行
复制
 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);      
      });
   });
}

顺便说一下,这是非常丑陋的:

代码语言:javascript
运行
复制
 if (artists.length != 0) {
   for (key in artists) {

只要做:

代码语言:javascript
运行
复制
  for(const artist of artists)
    promises.push(someApiCall(artist));

或者:

代码语言:javascript
运行
复制
  const promises = artists.map(someApiCall);
票数 2
EN

Stack Overflow用户

发布于 2018-04-03 10:52:54

简单的方法是使用已经存在的ORM,如、sequalizejs、等,它们为您返回承诺,而不是在本地MySQL驱动程序中运行、查找和创建单独的原始查询。您可以简单地使用API,比如查找或创建一些东西。

我在您的示例中解释了异步是如何工作的,我从您的示例中获取了一段代码。

代码语言:javascript
运行
复制
    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函数--这正是您所拥有的。有三件事你要注意,

  1. 您可以将其声明为异步函数,以便在默认情况下返回诺言。
  2. 如果它是一个同步函数,则可以简单地返回任何类似于普通函数的内容,避免使用异步。
  3. 就像你说的,你不能从回调中返回任何东西。因为它是异步的,所以您必须返回诺言。

所以代码可以更改为

代码语言:javascript
运行
复制
    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博客,以等待处理错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49627044

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档