尝试在循环中创建对象。
myarray=[1,1,1,1,1];
for (var k = 0; k < myarray.length; k++){
var id = myarray[k];
aFunctionCreatesParseObjectAndSave(id);
}
在我的aFunctionCreatesParseObjectAndSave(id)函数中,我试图检查是否有一个具有相同id的parse对象。 (用parsequery查看)如果我没有创建,只需更新。但如果没有对象创建它并保存。
function aFunctionCreatesParseObjectAndSave(id){
var query= new Parse.Query(MyParseObject);
query.equalTo("myId",id);
query.first().then(
function(result){
if(result === undefined){
// there isn't entry for this id
//create parseObject and fill it
...
newObject.set("id",id);
newObject.save();
}else{
// entry found for this id
//do update on result and save
...
result.save();
}
}
);
}
对于我的测试数组(所有元素都是相同的id),它应该只创建一个条目。但我有myarray.length计数对象:(
我该如何解决这个问题?
答案 0 :(得分:0)
承诺!
真正简短的回答是你连续五次检查,看看是否有任何东西存在,然后保存第一个对象。
好的,现在回答很久。
你的循环调用aFunctionCreatesParseObjectAndSave
。该函数可以实现其功能,但循环并不等待它完成它的工作。对象的查询和保存是异步的,因此函数会立即“返回”,即使它调用的查询继续运行。
希望我能说清楚发生了什么:
这里列出的第一个代码是一个单元测试,其中包含或多或少的代码,以及最后的测试,希望能够显示正在发生的事情....
// testing boilerplate 2 lines...
describe('my test', () => {
it('count', (done) => {
// ok, this is all "our code"
const MyParseObject = 'TestClass';
// a function to count number of records with a given id.
// Importantly, this function returns a promise.
const count = function count(id) {
return new Parse.Query(MyParseObject)
.equalTo('myId', id)
.count(); // <-- count returns a promise
}
// your function with all the ...'s filled in.
function aFunctionCreatesParseObjectAndSave(id){
var query = new Parse.Query(MyParseObject);
query.equalTo("myId",id);
query.first().then(
function(result){
if(result === undefined){
// there isn't entry for this id
//create parseObject and fill it
const newObject = new Parse.Object(MyParseObject);
newObject.set('myId',id);
// you don't wait for this promise to resolve!
newObject.save();
} else {
// entry found for this id
// do update on result and save
result.increment('count');
// this never gets called, and is never waited on...
result.save();
}
});
}
const myarray = [1,1,1,1,1];
for (var k = 0; k < myarray.length; k++){
var id = myarray[k];
aFunctionCreatesParseObjectAndSave(id);
}
// so what I'm doing here is waiting for
// 1 second, then counting the number
// of records with the same 'myId'.
// and then testing that each id in the array
// got a new object.
setTimeout(() => {
count(id)
// count will be 5 and that's one per element in myarray
.then(count => expect(count).toBe(myarray.length))
.then(done)
.catch(done.fail)
}, 1000); // 1,000 miliseconds is one second
});
});
下面是我如何“修复”代码只创建一个对象,并在每次迭代时递增一个计数器。
describe('my test', () => {
const MyParseObject = 'TestClass';
it('count', (done) => {
// This will call an array of functions that return promises in sequence.
const sequence = function sequence(tasks) {
return tasks.reduce((promise, task) => promise.then(() => task.call()), Promise.resolve());
}
function aFunctionCreatesParseObjectAndSave(id){
var query = new Parse.Query(MyParseObject);
query.equalTo("myId",id);
// Very important to return this promise!
return query.first().then(
function(result){
if(result === undefined){
// there isn't an entry for this id
//create parseObject and fill it
const newObject = new Parse.Object(MyParseObject);
newObject.set('myId', id);
newObject.set('count', 1);
// very important to return this promise!
return newObject.save();
} else {
// entry found for this id
//do update on result and save
result.increment('count');
// very important to return this promise!
return result.save();
}
});
}
const myarray = [1,1,1,1,1];
const promises = [];
for (var k = 0; k < myarray.length; k++){
var id = myarray[k];
// don't call the function, make an array of functions that call the functions.
promises.push(() => aFunctionCreatesParseObjectAndSave(id));
}
// We have an array promises that haven't even started to run.
// the function sequence() will now execute each promise
// in the array, then wait till its done and start the next
// promise.
sequence(promises)
.then(() => new Parse.Query(MyParseObject).find())
.then(results => {
// this test verifies that there is only one object now.
expect(results.length).toBe(1);
const theObj = results[0];
// the count member of the object should be 5, one for each
// id element of 1 in 'myarray'
expect(theObj.get('count')).toBe(myarray.length);
done();
})
.catch(done.fail);
});
});
我在这里做的测试是在nodejs服务器上运行单元测试的上下文中。我写了sequence
函数。 “在现实生活中”,特别是如果此代码在浏览器中运行,您需要使用像bluebird这样的库,然后使用mapSeries。