如何在node.js中使循环等待回调?

时间:2016-03-30 10:01:40

标签: javascript node.js mongodb

我有情景。我希望在mongodb中更新数据后执行循环。意思是:

var i = 0;
while (i< 5) {
    attendanceDataModel.update(query, condition).exec(function(error, data) {
        if (error) {
            console.log("Error @ 168 line in app.js File : \n" + err + "\n");
            i++;
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched.");
                i++;
            } else {
                console.log(currEmpId + " : successfully Logged Out ! :-)" + data + "\n");
                updateRecordNumber(currRecordNumber); 
                i++;  //wrong because it increases the value before updating in DB.
            }
        }
    });
}

var updateRecordNumber = function(currRecordNumber) {

    var condition = { deviceLogId: parseInt(currRecordNumber) };

    lastDeviceLogIdModel.update({}, condition).exec(function(error, data) {
        if (error) {
            console.log("Error @ 213 line in app.js File : \n" + err + "\n");
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched." + "\n");
            } else {
                console.log(currRecordNumber + " : DeviceLogId successfully Updated ! :-)");
      // I want to increase value of i here after updation in database
            }
        }
    });
}

现在,我想在函数updateRecordNumber成功更新后增加变量i值

6 个答案:

答案 0 :(得分:1)

最简单的方法是更改​​var updateRecordNumber = function(currRecordNumber, callback)之类的函数,然后更改调用:updateRecordNumber(currRecordNumber, function(){ i++ });

但我认为使用某种控制流方法是一种更好的解决方案,例如: PromisesAsync.js

P.S。当然你必须改变功能的身体:

var updateRecordNumber = function(currRecordNumber, callback) {
// all your async stuff
  callback();
}

答案 1 :(得分:1)

代码可以更改为:

var i = 0;

function startUpdation() {

  return attendanceDataModel.update(query, condition).exec(function(error, data) {
    if (error) {
        console.log("Error @ 168 line in app.js File : \n" + err + "\n");
        i++;
        if (i<5) {
            return startUpdation();
        }
        return;
    } else {
        if (data.length <= 0) {
            console.log("No Records Matched.");
            i++;
            if (i<5) {
                return startUpdation();
            }
            return;
        } else {
            console.log(currEmpId + " : successfully Logged Out ! :-)" + data + "\n");
            return updateRecordNumber(currRecordNumber).then(function (err, data){
                i++;
                if (i<5) {
                    return startUpdation();
                }
                return;
            }); 
        }
    }
});
}

function updateRecordNumber (currRecordNumber) {

var condition = { deviceLogId: parseInt(currRecordNumber) };

return lastDeviceLogIdModel.update({}, condition).exec(function(error, data) {
    if (error) {
        console.log("Error @ 213 line in app.js File : \n" + err + "\n");
    } else {
        if (data.length <= 0) {
            console.log("No Records Matched." + "\n");
        } else {
            console.log(currRecordNumber + " : DeviceLogId successfully Updated ! :-)");
        }
    }
});
}

startUpdation();

请尝试此解决方案。

答案 2 :(得分:1)

如果你使用函数updateRecordNumber并在then()中写增量调用会更好。

答案 3 :(得分:0)

您的while循环是同步的,并不考虑以后有时会返回对数据库操作的响应。 通过递归重新安排操作(在5次尝试后退出),您需要在不成功的操作后重新查询:

function execute(count, callback) {
    if (count == 5) {
        return callback(new Error('meh...'))
    }

    loadSomethingAsync(function(error, result) {
        if (error || !result) {
            return execute(count++, callback)
        }

        callback(null, result)
    })
}

execute(0, function(error, result) {
    if (error) {
        return console.log('after 5 tries still no result or error...')
    }

    console.log('yay, async op has finished!')
})

答案 4 :(得分:0)

如何将循环重构为自身成为回调的一部分?像这样:

var i = 0,

    fna = function (error, data) {
        if (error) {
            console.log("Error @ 168 line in app.js File : \n" + err + "\n");
            fnc(); //i++;
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched.");
                fnc(); //i++;
            } else {
                console.log(currEmpId + " : successfully Logged Out ! :-)" + data + "\n");
                updateRecordNumber(currRecordNumber);
                //i++;  //wrong because it increases the value before updating in DB.
            }
        }
    },

    updateRecordNumber = function (currRecordNumber) {
        var condition = {
            deviceLogId : parseInt(currRecordNumber, 10)
        };

        lastDeviceLogIdModel.update({}, condition).exec(fnb);
    },

    fnb = function (error, data) {
        if (error) {
            console.log("Error @ 213 line in app.js File : \n" + err + "\n");
        } else {
            if (data.length <= 0) {
                console.log("No Records Matched." + "\n");
            } else {
                console.log(currRecordNumber + " : DeviceLogId successfully Updated ! :-)");
                // I want to increase value of i here after updation in database
                fnc();
            }
        }
    },

    fnc = function () {
        i++;

        if (i < 5) {
            attendanceDataModel.update(query, condition).exec(fna);
        }
    };

attendanceDataModel.update(query, condition).exec(fna);

答案 5 :(得分:0)

您可以在节点js中使用同步模块。您可以看到我的博客enter link description here