我对 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/