DB事务中的异步等待循环

时间:2020-01-13 21:15:38

标签: javascript

有一个函数,我为每个记录循环一个forEach,我进行了db调用以检查某些字段。 因此,问题在于html变量的返回值为空的“”。 当我用+ = populateDownloadListFunction()填充html变量时,持续时间很长,所以return html返回“”

我认为是由于数据库事务异常

   const checkIfDownloaded = async (workflow3andwip) => {

    let html = "";         
     app.db.transaction((tx) => {
       workflow3andwip.forEach(row => 
            tx.executeSql('SELECT * FROM FORM_SUBMISSION WHERE sub_id=? AND DOWNLOADED = 1', [row.id],
              (tx2, results2) => {
                  html += populateDownloadListFunction(results2);

              }, app.onError)
        );
    });
    return html;
};

所以我尝试在==>上添加await和.map而不是forEach awaitworkflow3andwip.map(row =>

和html + =等待populateDownloadListFunction(results2);

但是不会编译 那么我该如何解决呢??

编辑:我添加了

      for(let i=0; i<workflow3andwip.lenght; i++{
//tx.executeSql .....
     }

但是html仍然是“”空字符串,但是如果我将html附加到$(#tableId)上,它会显示值,但是我需要在循环结束之前完成html

             for (var i = 0; i < workflow3andwip.length; i++) {
            tx.executeSql('SELECT * FROM FORM_SUBMISSION WHERE sub_id=? AND DOWNLOADED = 1', [workflow3andwip[i].id],
            async (tx2, results2) => {

                html += await populateDownloadListFunction(params);

            }, app.onError)
         }

但返回html仍为“”为空

1 个答案:

答案 0 :(得分:0)

您的SQL API函数是异步的,但它们不会产生诺言,这是asyncawait所需要的。

因此,除非您的API可以立即提供承诺,否则请使用new Promise将其变为承诺。

无关,但我不会为每个单独的row.id发出单独的SQL查询。相反,请首先收集所有这些ID,然后使用in运算符执行一个 SQL查询。

这是您可以完成上述所有操作的方法:

const checkIfDownloaded = (workflow3andwip) => 
    new Promise((resolve) =>
        app.db.transaction((tx) => {
            let args = workflow3andwip.map(row => row.id);
            let params = Array(workflow3andwip.length).fill("?").join(",");
            tx.executeSql(
                'SELECT * FROM FORM_SUBMISSION WHERE sub_id in (' + params + ') AND DOWNLOADED = 1', 
                args,
                (tx2, results2) => resolve(populateDownloadListFunction(results2)), 
                app.onError
            );
        });
    );

请注意,当您致电checkIfDownloaded时,您将获得一个诺言,而不是HTML。您需要先让异步过程完成,这将解决承诺。例如,您可以这样做:

 checkIfDownloaded(workflow3andwip).then(console.log); // will print the HTML asynchronously.