Javascript,如何等待多重承诺

这个问题在这里已经有了答案:

  • 如何将现有的回调API转换为承诺? 17个答案

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

    有关更多信息,请参见Async FunctionPromiseArray.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函数,这正是你所拥有的。 这里需要注意的三件事情,

  • 你声明它是一个异步函数,所以它在默认情况下返回promise。
  • 它可以简单地返回任何类似普通函数,如果它是一个同步函数,则避免使用异步。
  • 正如你所说,你不能从回调中返回任何东西。 由于它是异步的,你必须返回承诺。
  • 所以代码可以更改为

        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

    上一篇: Javascript, how to await multiple promises

    下一篇: async await callback is not a function