简体   繁体   English

等待它解决promise然后整齐插入

[英]Wait for it to resolve promise and then insert neatly

I've been watching all morning because this code doesn't work for me.我整个上午都在看,因为这段代码对我不起作用。

I want once the promise is resolved, the "then" get its last inserted ID (the promise) and neatly insert into the other table.我希望一旦承诺得到解决,“then”就会获得它最后插入的 ID(承诺)并整齐地插入到另一个表中。 Currently first paints all the promise and then just then or disorderly ...目前先把所有的承诺都涂上,然后就这样或无序......

con.query("SELECT ID FROM wp_posts ORDER BY ID DESC LIMIT 0,1;", function(err, result, fields) {
  console.log(result);
  for (var i = 0; i < getData.length; i++) {
    var source = getData[i]["source"];
    var text = getData[i]["text"];
    var quality = getData[i]["quality"];
    new Promise(function(resolve, reject) {
      var sql = "INSERT INTO `wp_posts` ( `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`,`post_excerpt`, `post_status`,`comment_status`, `ping_status`,`post_password`, `post_name`,`to_ping`,`pinged`, `post_modified`, `post_modified_gmt`,`post_content_filtered`,`post_parent`, `guid`,`menu_order`, `post_type`, `post_mime_type`,`comment_count`) VALUES (1, '" + fhoy + "', '" + fhoy + "', '', '" + make + "','', 'publish', 'closed', 'closed','','" + make + "','','', '" + fhoy + "', '" + fhoy + "','', '" + result[0].ID + "','','0', 'dt_links','' ,0);";
      con.query(sql, function(err, result) {
        if (err) throw err;
        resolve(result);
        console.log("1 registro link insertado");
      });
    }).then(function() {
      //new Promise(function(resolve, reject) {
      con.query("SELECT ID FROM wp_posts WHERE post_type='dt_links' ORDER BY ID DESC LIMIT 0,1;", function(err, result, fields) {
        console.log(result);
        var sql = "INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (" + result[0].ID + ",'_dool_url', '" + source + "'),(" + result[0].ID + ",'_dool_type','" + text + "'),(" + result[0].ID + ",'_dool_quality','" + quality + "');";

        con.query(sql, function(err, result) {
          if (err) throw err;
          console.log("1 registro link meta insertado");
        });
        // });
      });
    });
  }
});

So the SQL injection vulnerabilities aside, you may have a better time with a promisified con.query function, here called queryP() .因此,撇开 SQL 注入漏洞不谈,您可能会更好地使用承诺的con.query函数,这里称为queryP()

I'm not sure I could capture the original logic of your code since it was reusing result , etc., but the idea should be there.我不确定我是否可以捕获代码的原始逻辑,因为它重用了result等,但这个想法应该在那里。

Do note though that there is a possible problem here in that if multiple concurrent requests modify wp_posts , the post IDs you're modifying may change.请注意,这里可能存在一个问题,如果多个并发请求修改wp_posts ,则您正在修改的帖子 ID 可能会更改。 You may want to look at this to get the last inserted ID .您可能需要查看此内容以获取最后插入的 ID

function queryP(con, sql, variables = []) {
  return new Promise((resolve, reject) => {
    con.query(sql, variables, (err, result, fields) => {
      if (err) {
        return reject(err);
      }
      return resolve({ result, fields });
    });
  });
}

async function processDataThing(con, result, dataThing) {
  var source = dataThing["source"];
  var text = dataThing["text"];
  var quality = dataThing["quality"];
  const r1 = await queryP(
    con,
    "INSERT INTO `wp_posts` ( `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`,`post_excerpt`, `post_status`,`comment_status`, `ping_status`,`post_password`, `post_name`,`to_ping`,`pinged`, `post_modified`, `post_modified_gmt`,`post_content_filtered`,`post_parent`, `guid`,`menu_order`, `post_type`, `post_mime_type`,`comment_count`) VALUES (1, '" +
      fhoy +
      "', '" +
      fhoy +
      "', '', '" +
      make +
      "','', 'publish', 'closed', 'closed','','" +
      make +
      "','','', '" +
      fhoy +
      "', '" +
      fhoy +
      "','', '" +
      result[0].ID +
      "','','0', 'dt_links','' ,0);",
  );
  console.log("1 registro link insertado");
  const r2 = await queryP(
    con,
    "SELECT ID FROM wp_posts WHERE post_type='dt_links' ORDER BY ID DESC LIMIT 0,1",
  );
  const result2 = r2.result;
  const r3 = await queryP(
    con,
    "INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (" +
      result2[0].ID +
      ",'_dool_url', '" +
      source +
      "'),(" +
      result2[0].ID +
      ",'_dool_type','" +
      text +
      "'),(" +
      result2[0].ID +
      ",'_dool_quality','" +
      quality +
      "');",
  );
}

// ...

async function doThings(con, getData) {
  const { result } = await queryP(con, "SELECT ID FROM wp_posts ORDER BY ID DESC 
LIMIT 0,1");
  const dataThingPromises = getData.map(dataThing => processDataThing(con, result, dataThing));
  return await Promise.all(dataThingPromises);
}

// ...

doThings(con, getData).then(() => console.log("All done!"));

Here is an example of how much cleaner things can be if you use the promise-based interface built into mysql2 to sequence all your operations properly:下面是一个示例,说明如果您使用 mysql2 中内置的基于 Promise 的接口来正确地对所有操作进行排序,可以使事情变得更加清晰:

// using mysql2/promise
// parent function must be declared async

try {
    let posts = await con.query("SELECT ID FROM wp_posts ORDER BY ID DESC LIMIT 0,1;");
    console.log(posts);
    for (const post of posts) {
        const source = post.source;
        const text = post.text;
        const quality = post.quality;

        let sql = "INSERT INTO `wp_posts` ( `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`,`post_excerpt`, `post_status`,`comment_status`, `ping_status`,`post_password`, `post_name`,`to_ping`,`pinged`, `post_modified`, `post_modified_gmt`,`post_content_filtered`,`post_parent`, `guid`,`menu_order`, `post_type`, `post_mime_type`,`comment_count`) VALUES (1, '" + fhoy + "', '" + fhoy + "', '', '" + make + "','', 'publish', 'closed', 'closed','','" + make + "','','', '" + fhoy + "', '" + fhoy + "','', '" + posts[0].ID + "','','0', 'dt_links','' ,0);";
        await con.query(sql);
        console.log("1 registro link insertado");

        let result = con.query("SELECT ID FROM wp_posts WHERE post_type='dt_links' ORDER BY ID DESC LIMIT 0,1;")
        console.log(result);

        sql = "INSERT INTO wp_postmeta (post_id, meta_key, meta_value) VALUES (" + result[0].ID + ",'_dool_url', '" + source + "'),(" + result[0].ID + ",'_dool_type','" + text + "'),(" + result[0].ID + ",'_dool_quality','" + quality + "');";
        await con.query(sql);
        console.log("1 registro link meta insertado");
    }
} catch(e) {
    // handle all db errors here
}

Not only is this a lot simpler to read and understand, but it also sequences each of your database operations and collects all the error handling to one place (you had basically no error handling before).这不仅更易于阅读和理解,而且还将您的每个数据库操作排序并将所有错误处理收集到一个地方(您之前基本上没有错误处理)。

List of changes:更改列表:

  1. Switch to mysql2/promise so we can use the built-in promise interface.切换到 mysql2/promise 以便我们可以使用内置的 promise 接口。
  2. Use async and await to make sequencing asynchronous database operations a lot simpler to code使用asyncawait使异步数据库操作的排序更易于编码
  3. Use try/catch to catch and handle all database errors in one place (you had no reasonable error handling before)使用try/catch在一个地方捕获和处理所有数据库错误(您之前没有合理的错误处理)
  4. Switch to for/of as a more convenient way to iterate an array切换到for/of作为迭代数组的更方便的方法
  5. Replace all var declarations with const or let as appropriate.根据需要将所有var声明替换为constlet
  6. Switch syntax from things like getData[i]["quality"] to getData[i].quality because it's just simpler and the quotes and brackets are not needed around a simple property name.将语法从getData[i]["quality"]切换到getData[i].quality因为它更简单,并且不需要在简单的属性名称周围使用引号和括号。

Open Issues:开放式问题:

  1. Your first query in the for loop is exactly the same every time through the loop.您在for循环中的第一个查询在每次循环中都完全相同。 That does not seem correct.这似乎不正确。 The only reference to result in that original query was result[0].ID , but that will be exactly the same value every time through the loop so something is apparently not correct with that. result在原始查询中的唯一引用是result[0].ID ,但每次通过循环都会是完全相同的值,因此某些内容显然不正确。 I don't think you want to be inserting the same record everytime through the loop.我认为您不想每次都通过循环插入相同的记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM