节点js foreach完成功能

时间:2017-06-20 23:06:08

标签: node.js foreach sequence

使用setTimeout时,在foreach完成后应该使用什么?

app.post('/grid', function(req, res){
   getResults(req.body.idarray, function(callback){
       res.send(callback);
   });
});
function getResults(userIds, callback) {
    var totalresult = [];
    userIds.forEach(function (user) {
        sequence
            .then(function (next) {
                db.query('SELECT given FROM books WHERE user_id = ?', [user.userId], function (err2, result) {
                    if (err2) throw err2;
                    next(err, result);
                });
            })
            .then(function (next, err, books) {
                db.query('SELECT received FROM encycs WHERE user_id = ?', [user.userId], function (err3, result2) {
                    if (err3) throw err3;
                    next(err, result2, books);
                });
            })
            .then(function (next, err, books, encycs ) {
                Calculation(books, encycs, function (cb) {
                    totalresult.push(cb);
                });
                next();
            });
    });
    setTimeout(function() {
        console.log(totalresult);  // output ok.
        return callback(totalresult); // returning as expected
    }, 2000);
}

我不知道totalresult.length是什么。所以我无法检查长度。

1 个答案:

答案 0 :(得分:1)

因此,根据您的用例,您需要以某种方式调用回调并将totalresult传递给它,因为这是您的外部代码,路径中的代码所期望的。 为此,您可以在调用第三个.then语句的下一个之前调用回调。就像那样。

        ...
        .then(function (next, err, books, encycs ) {
            Calculation(books, encycs, function (cb) {
                totalresult.push(cb);
            });
            callback(totalresult);
            next();
            //console.log(totalresult); //output OK.
        });

这可能有用。

更新1

您的代码很难遵循。无法赶上它的逻辑。我建议你采取Promises方法。我准备了那个可行的解决方案。它可能包含很少的错误,但它代表了你想要实现的目标的主要思想,以及它是如何完成的。

app.post("/grid", (req, res) => {
    getResults(req.body.idarray)
        .then(data => {
            res.status(200).json(data);
        })
        .catch(err => {
            console.error("Error occured", err);
            res.status(500).json(err);
        });
});

function getResults(userIds) {
    let promises = userIds.map(loadCalculation);
    //this will wait until all loadings are done
    return Promise.all(promises);
}

function loadCalculation(user) {
    //parallel loading of the books and encycs
    return Promise.all([loadBooks(user), loadEncycs(user)])
        .then(results => {
            let books = results[0];
            let encycs = results[1];

            let totalresult = [];

            Calculation(books, encycs, function (cb) {
                totalresult.push(cb);
            });

            return totalresult;
        });
}

function loadBooks(user) {
    return makeQuery('SELECT given FROM books WHERE user_id = ?', user);
}

function loadEncycs(user) {
    return makeQuery('SELECT received FROM encycs WHERE user_id = ?', user);
}

function makeQuery(query, user) {
    return Promise((resolve, reject) => {
        db.query(query, [user.userId], function (err, result) {
            if(err) {
                reject(err);
            } else {
                resolve(result);
            }
        });        
    });
}

请注意,这不是从数据库加载数据的高效方式,至少,我确信您可以使用单个查询加载所有书籍和encycs,因为您是使用SQL,它是非常灵活的语言。