javascript解析承诺 - 更新记录

时间:2017-03-08 18:37:49

标签: javascript parse-platform promise

我是javascript和承诺的新手,并且很难弄清楚这个。

我需要做的是搜索一组记录。一旦我拥有它们,循环并添加每个记录中的字段值。然后将该值与传入的值结合使用,以计算每个记录的新值。基本上我正在做的是:

    var paymentQuery = new Parse.Query("MemberPayment");
    paymentQuery.equalTo("type", type);
    paymentQuery.find().then(
        function(payments) {
            var totalPaidIn = 0;
            for (var i = 0; i < payments.length; i++) {
                var payment = payments[i];
                totalPaidIn += payment.get("amountPaidIn");
            }

            // Total the amount 
            var unitValue = 100.0/totalPaidIn;
            unitValue = unitValue.toFixed(3);

            for (var i = 0; i < payments.length; i++) {
                var payment = payments[i];
                var paidIn = payment.get("amountPaidIn");
                var new = Math.round(((paidIn * unitValue) / 100) * amountPassedIn);
                payment.set("amountPaidOut", paidIn + new);
                payment.save(null, { useMasterKey: true });
            }
        }
    )

基本上,我需要的是同步保存。因为我从记录中获取值,更新它,然后保存。我所看到的是,如果我有两组三个记录,即这个代码被调用两次,并且我的原始值amountPaidIn在每个记录中都是0,那么两次都通过第二个循环,我&#39; m得到一个值0.所以第一次保存似乎不是在我第二次进入循环时发生的。

所以我只是不知道应该如何使用promises?

修改

我忽略了这一切都是在循环中发生的。

更新

dan,我完全按照原样复制你的代码,除了传递一个数值,而不是一个类型,如下:

function updateAllPayments() {
    var amounts = [ 1000, 2000, 3000 ];
    var promises = amounts.map(function(amountWon) {
        return updatePaymentsWithAmount(amountWon);
    });
    return Parse.Promise.when(promises);
}

我在添加每个承诺之前添加了一个日志声明:

var payment = payments[i];
var paidIn = payment.get("amountPaidIn");
var paidOut = payment.get("amountPaidOut");
var add = Math.round(((paidIn * unitValue) / 100) * amountWon);
payment.set("amountPaidOut", paidOut + add);
console.log("before savepromise add is " + add + " paid in " + paidIn + " paid out " + paidOut);
var savePromise = payment.save(null, { useMasterKey: true });
promises.push(savePromise);

这是输出:

amount won is 3000
before savepromise add is 1286 paid in 15 paid out 0
before savepromise add is 857 paid in 10 paid out 0
before savepromise add is 857 paid in 10 paid out 0
amount won is 1000
before savepromise add is 429 paid in 15 paid out 0
before savepromise add is 286 paid in 10 paid out 0
before savepromise add is 286 paid in 10 paid out 0
amount won is 2000
before savepromise add is 857 paid in 15 paid out 0
before savepromise add is 571 paid in 10 paid out 0
before savepromise add is 571 paid in 10 paid out 0

数据库中的最终值是:

857
286
571

因此,仍然会出现查询异步运行,并且在执行任何保存之前所有3个查询都会启动。

2 个答案:

答案 0 :(得分:1)

Promise.When很好地涵盖了这个案例。当所有传递给它的承诺解决时,它就会解决。

编辑 OP提供了额外的上下文:find也是循环的一部分。这样的问题通常可以通过一些额外的抽象来帮助。

让我把我原来的建议放在一个函数体中,称之为updateMemberPaymentsWithType ...

function updateMemberPaymentsWithType(type) {
    var paymentQuery = new Parse.Query("MemberPayment");
    paymentQuery.equalTo("type", type);
    paymentQuery.find().then(function(payments) {
        var totalPaidIn = 0;
        for (var i = 0; i < payments.length; i++) {
            var payment = payments[i];
            totalPaidIn += payment.get("amountPaidIn");
        }

        // Total the amount 
        var unitValue = 100.0/totalPaidIn;
        unitValue = unitValue.toFixed(3);

        var promises = [];

        for (var i = 0; i < payments.length; i++) {
            var payment = payments[i];
            var paidIn = payment.get("amountPaidIn");
            var new = Math.round(((paidIn * unitValue) / 100) * amountPassedIn);
            payment.set("amountPaidOut", paidIn + new);
            var savePromise = payment.save(null, { useMasterKey: true });
            promises.push(savePromise);
        }
        // now promises is an array of save promises
        return Parse.Promise.when(promises);
    });
}

注意它如何返回Promise.when()创建的promise。现在你有一个可以在别处使用的promise-returns函数,包括从循环中调用它,如:

function updateAllPayments() {
    var types = [ "typeA", "typeB", "typeC" ];
    var promises = types.map(function(type) {
        return updateMemberPaymentsWithType(type);
    });
    return Parse.Promise.when(promises);
}

注意这个人如何收集承诺,并返回一个解决所有承诺的承诺。您可以使用此样式通过非常清晰,可测试的代码构建异步操作的任意复杂组合。最终在Parse中,一些云函数会想要像这样调用它....

Parse.Cloud.define("someCloudFunction", function(request, response) {
    updateAllPayments().then(function(result) {
        response.success(result);
    }, function(error) {
        response.error(error);
    });
});

答案 1 :(得分:0)

如果你想运行异步代码&#34;顺序&#34;,你可以很容易地使用promises - 承诺链接是关键

var paymentQuery = new Parse.Query("MemberPayment");
paymentQuery.equalTo("type", type);
paymentQuery.find().then(
    function(payments) {
        var totalPaidIn = 0;
        for (var i = 0; i < payments.length; i++) {
            var payment = payments[i];
            totalPaidIn += payment.get("amountPaidIn");
        }

        // Total the amount 
        var unitValue = 100.0/totalPaidIn;
        unitValue = unitValue.toFixed(3);
        var promise = Promise.resolve(); // an initial promise tp start the chain
        for (var i = 0; i < payments.length; i++) {
            var payment = payments[i];
            var paidIn = payment.get("amountPaidIn");
            var add = Math.round(((paidIn * unitValue) / 100) * amountPassedIn);
            payment.set("amountPaidOut", paidIn + add);
            // chain the requests so they run one after the other
            promise = promise.then(function() {
                return payment.save(null, { useMasterKey: true });
            });
        }
        return promise;
    }
).then(function() {
    // at this point all payments are saved
});

当然,以上假设payment.save返回promise - 我还将var new更改为var add,因为问题中的代码实际上无效