Parse Server Cloud Code 函数在 promise 实现之前完成
ParseServer Cloud Code function finishing before promise has been fulfilled
我有一个场景,我试图确定一家公司当月有多少新 "payers"。我的代码有效,我可以记录结果并获得公司预期的新付款人数量。但是,该方法返回 0,因为最终代码是在 Promise 完成之前执行的。
我认为问题是 promise 不是链接的,而是嵌套的,我尝试链接它们,但它只是给出了错误。下面的代码有什么明显的错误吗?
Parse.Cloud.define('cloudMethod', function(request, response) {
if (!request.user) {
response.error('Invalid User')
return
}
// Set up now date
const now = new Date()
const thisMonthYear = now.getMonth().toString() + now.getFullYear().toString()
// Setup empty array to hold new monthly payer matches
const newMonthlyDonors = []
// Setup User query
const User = Parse.Object.extend('User')
const userQuery = new Parse.Query(User)
// Step 1: Get company pointer from user
userQuery
.equalTo('username', request.user.get('username'))
.first()
.then(function(user) {
// Step 2: Count payers for that company
var Payment = Parse.Object.extend('Payment')
var paymentQuery = new Parse.Query(Payment)
paymentQuery.equalTo('company', user.get('company'))
// Create a trivial resolved promise as a base case.
var promise = Parse.Promise.as()
paymentQuery.distinct('user').then(function(results) {
// Step 3: Loop through each distinct payer
_.each(results, function(result) {
// For each item, extend the promise with a function.
promise = promise.then(function() {
// Setup new Payment query
const firstPaymentQuery = new Parse.Query(Payment)
/*
Step 4:
Query Payment class by this user,
set payment dates in ascending order
and then take the first one.
*/
firstPaymentQuery
.equalTo('user', result)
.ascending('paymentDate')
.first()
.then(function(firstPayment) {
// Set up user date
const firstPaymentDate = new Date(firstPayment.get('paymentDate'))
const firstPaymentMonthYear = firstPaymentDate.getMonth().toString() + firstPaymentDate.getFullYear().toString()
/*
Step 5:
See if the user's first payment date is equal to the current month
*/
if (firstPaymentMonthYear === thisMonthYear) {
return newMonthlyDonors.push(result)
}
else {
return
}
}, function(error) {
response.error('Query to get users first payment date failed')
})
})
})
return promise
}).then(function() {
/*
FIXME:
This is getting called before the queries above can run.
Which is why it's returning 0...
*/
// Return the matches for this month
response.success(newMonthlyDonors.length)
}, function(error) {
response.error('total user count for company failed')
})
},
function(error) {
console.log('Error retrieving User')
console.log(error)
})
})
我会考虑创建一个包含您所有承诺的数组 const promises = [];
,因此每次您有一个承诺时,您都将其放入数组中。
那么你return所有的承诺都是这样的:return Promise.all(promises);
Parse.Cloud.define('cloudMethod', function(request, response) {
...
const promises = [];
promises.push(firstPaymentQuery
.equalTo('user', result)
.ascending('paymentDate')
.first()
.then(function(firstPayment) { ...
);
...
// callback if all promises have finished
Promise.all(promises).then(() => {
// success
});
});
这是我经常做的。
问题是我没有返回查询作为 _.each()
中调用的第一个承诺的结果,因此从未返回该查询中的返回结果。
引用问题中的大块代码:
这个:
/*
Step 4:
Query Payment class by this user,
set payment dates in ascending order
and then take the first one.
*/
firstPaymentQuery…
需要这样:
/*
Step 4:
Query Payment class by this user,
set payment dates in ascending order
and then take the first one.
*/
return firstPaymentQuery…
我有一个场景,我试图确定一家公司当月有多少新 "payers"。我的代码有效,我可以记录结果并获得公司预期的新付款人数量。但是,该方法返回 0,因为最终代码是在 Promise 完成之前执行的。
我认为问题是 promise 不是链接的,而是嵌套的,我尝试链接它们,但它只是给出了错误。下面的代码有什么明显的错误吗?
Parse.Cloud.define('cloudMethod', function(request, response) {
if (!request.user) {
response.error('Invalid User')
return
}
// Set up now date
const now = new Date()
const thisMonthYear = now.getMonth().toString() + now.getFullYear().toString()
// Setup empty array to hold new monthly payer matches
const newMonthlyDonors = []
// Setup User query
const User = Parse.Object.extend('User')
const userQuery = new Parse.Query(User)
// Step 1: Get company pointer from user
userQuery
.equalTo('username', request.user.get('username'))
.first()
.then(function(user) {
// Step 2: Count payers for that company
var Payment = Parse.Object.extend('Payment')
var paymentQuery = new Parse.Query(Payment)
paymentQuery.equalTo('company', user.get('company'))
// Create a trivial resolved promise as a base case.
var promise = Parse.Promise.as()
paymentQuery.distinct('user').then(function(results) {
// Step 3: Loop through each distinct payer
_.each(results, function(result) {
// For each item, extend the promise with a function.
promise = promise.then(function() {
// Setup new Payment query
const firstPaymentQuery = new Parse.Query(Payment)
/*
Step 4:
Query Payment class by this user,
set payment dates in ascending order
and then take the first one.
*/
firstPaymentQuery
.equalTo('user', result)
.ascending('paymentDate')
.first()
.then(function(firstPayment) {
// Set up user date
const firstPaymentDate = new Date(firstPayment.get('paymentDate'))
const firstPaymentMonthYear = firstPaymentDate.getMonth().toString() + firstPaymentDate.getFullYear().toString()
/*
Step 5:
See if the user's first payment date is equal to the current month
*/
if (firstPaymentMonthYear === thisMonthYear) {
return newMonthlyDonors.push(result)
}
else {
return
}
}, function(error) {
response.error('Query to get users first payment date failed')
})
})
})
return promise
}).then(function() {
/*
FIXME:
This is getting called before the queries above can run.
Which is why it's returning 0...
*/
// Return the matches for this month
response.success(newMonthlyDonors.length)
}, function(error) {
response.error('total user count for company failed')
})
},
function(error) {
console.log('Error retrieving User')
console.log(error)
})
})
我会考虑创建一个包含您所有承诺的数组 const promises = [];
,因此每次您有一个承诺时,您都将其放入数组中。
那么你return所有的承诺都是这样的:return Promise.all(promises);
Parse.Cloud.define('cloudMethod', function(request, response) {
...
const promises = [];
promises.push(firstPaymentQuery
.equalTo('user', result)
.ascending('paymentDate')
.first()
.then(function(firstPayment) { ...
);
...
// callback if all promises have finished
Promise.all(promises).then(() => {
// success
});
});
这是我经常做的。
问题是我没有返回查询作为 _.each()
中调用的第一个承诺的结果,因此从未返回该查询中的返回结果。
引用问题中的大块代码:
这个:
/*
Step 4:
Query Payment class by this user,
set payment dates in ascending order
and then take the first one.
*/
firstPaymentQuery…
需要这样:
/*
Step 4:
Query Payment class by this user,
set payment dates in ascending order
and then take the first one.
*/
return firstPaymentQuery…