javascript parse Promise - 更新记录

标签 javascript parse-platform promise

我对 javascript 很陌生,并且 promise ,但我很难掌握这个。

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

    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,那么两次通过第二个循环,我都会得到一个值0. 因此,当我第二次执行循环时,第一次保存似乎尚未发生。

所以我只是不明白使用 promise 应该是什么样子?

编辑:

我忘记补充一点,这一切都是在循环中发生的。

更新:

dan,我完全按照原样复制了您的代码,除了传递数值而不是类型之外,如下所示:

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

在添加每个 promise 之前我放置了一条日志语句:

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 个查询在任何保存执行之前启动。

最佳答案

Promise.when 很好地涵盖了这种情况。当传递给它的所有 promise 都解决时,它就会解决。

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

让我们将我最初的建议放入函数体中,将其命名为 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 返回函数,包括从循环中调用它,如下所示:

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

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

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

关于javascript parse Promise - 更新记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42679313/

相关文章:

javascript - Vue Array 转换为 Proxy 对象

javascript - 检查用户是否可以打开网站中的文件类型

javascript d3 selectAll 转换为循环

javascript - 用于在网站上发布并将推送发送到移动设备的表单

android - 将数据从外部服务器保存到 Parse.com

javascript - Angular Promise 使用多个 http 请求

javascript - 从 xml 文件获取一些信息的 xslt 和 xpath 在 JavaScript 中不起作用

parse-platform - SNS通知调度

typescript - Deno(typescript) 中的 Promise { <pending> }

node.js - 我如何 stub Promise 以便我的测试可以同步运行?