如何在Javascript中异步使用对象?

时间:2015-09-15 18:50:06

标签: javascript node.js express

在进入查询之前,定义了issues对象,在问题查询中它是未定义的。我尝试了在相同类型的帖子中提到的解决方案,但它没有用。代码中的注释进一步解释了这个问题。

var createIssues = function createIssues(rows, wrap) {
    var issues = [];

    for (var i = 0; i < rows.length; i++) {

        // Processing code redacted

        issues.push({
            id       : rows[i].id,
            // Other field redacted
        });


        // ISSUES OBJECT CORRECT HERE
        console.log(JSON.stringify(issues[i]))

        // Query comments for individual post

        connection.query(
            "SELECT C.id, C.elementID, C.googleID, C.time, C.body FROM comments C WHERE elementID = ? AND approved = 1", issues[i].id,
            function (err, rows_comments) {

                // ISSUES OBJECT UNDEFINED HERE
                console.log(JSON.stringify(issues[i]))

                // More code redacted
            }
        )
    }

    return issues;
}

我尝试将其作为函数传递,类似于我在网上的解释中所发现的,但现在它说“TypeError:undefined不是函数”

var createIssues = function createIssues(rows, wrap) {

    var issues = []; // Create issues array

    // Loop throug every issue that was
    // returned by the SQL query.
    for (var i = 0; i < rows.length; i++) {

      // Redacted processing code

        issues.push({
            id       : rows[i].id,
            // Redacted extra fields
        });

        (function(issues) {

            connection.query(
                "SELECT C.id, C.elementID, C.googleID, C.time, C.body FROM comments C WHERE elementID = ? AND approved = 1", issues[i].id,
                function (err, rows_comments) {

        // Can't access issues here, undefined

                }
            )

        })(issues);

    }

    return issues;
}

2 个答案:

答案 0 :(得分:2)

这里的问题是你将整个问题数组传递给了你的生命而不仅仅是个体,这使得生活毫无意义,因为它没有解决它要解决的问题。

    (function(issue) {

        connection.query(
            "SELECT C.id, C.elementID, C.googleID, C.time, C.body FROM comments C WHERE elementID = ? AND approved = 1", issue.id,
            function (err, rows_comments) {

                // worky

            }
        )

    })(issues[i]);

也就是说,您可以通过使用可用于所有阵列的forEach方法来完全避免此问题。如果你有一个数组,并且你需要以1的步长循环它,那么就没有理由不使用数组方法而不是for循环。

var createIssues = function createIssues(rows, wrap) {

    var issues = []; // Create issues array

    // Loop throug every issue that was
    // returned by the SQL query.
    rows.forEach(function (row, index) {

      // Redacted processing code
        var issue = {
            id       : row.id,
            // Redacted extra fields
        }
        issues.push(issue);

        connection.query(
            "SELECT C.id, C.elementID, C.googleID, C.time, C.body FROM comments C WHERE elementID = ? AND approved = 1", issue.id,
            function (err, rows_comments) {

                // worky

            }
        )
    });

    return issues;
}

请注意,在完成所有异步工作之前,issues将返回到调用范围,这意味着您执行的任何代替// worky注释的操作都不会生效时间过了。

答案 1 :(得分:0)

我认为当你返回issues对象时,你仍然会遇到问题,因为你是异步修改它的。对于此问题,您无法在查询回调中访问i但是您返回的行具有相同的ID,这应该足以进行查找:

    connection.query(
        "SELECT C.id, C.elementID, C.googleID, C.time, C.body FROM comments C WHERE elementID = ? AND approved = 1", issues[i].id,
        function (err, rows_comments) {

            // ISSUES OBJECT UNDEFINED HERE
            // console.log(JSON.stringify(issues[i])) //i is not what you expect here
            console.log(JSON.stringify(issues[row_comments.id])); //the ID comes back in the query

            // More code redacted
        }
    )