我是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个查询都会启动。
答案 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
,因为问题中的代码实际上无效