将数据插入集合时的 Promises 和代码超时问题
Problem with Promises and code timeout when inserting data into a collection
我正在尝试验证对象是否已存在于 wix 集合中,以及它是否会取消对数据库的 inset() 调用
import wixData from "wix-data";
export function Memberships_beforeInsert(item, context) {
var name = item.firstName + item.lastName;
name = name.toLowerCase();
wixData.query(context.collectionName)
.find()
.then((res) => {
var members = res.items;
var len = res.length;
console.log(len)
for (var i = 0; i < len; i++) {
let member = members[i];
let memberName = member.firstName + member.lastName;
memberName = memberName.toLowerCase();
if (memberName === name) {
let toUpdate = {
'_id': member._id
}
wixData.update(context.collectionName, toUpdate)
return null;
}
return item;
}
});
//toHere
}
我对 wixCode 还很陌生,但我希望这会等到 .then() 被调用,然后 return 如下,但是由于 wixCode 使用承诺,代码会立即转到 //toHere
代码部分,它在其中找到 return 并取消调用。它将数据添加到数据库而不是 returning null.
好的,所以当我们查看您的代码时,您似乎想要找到与您尝试插入到会员资格的记录匹配的记录,然后中止插入并执行更新(如果存在)。更好的方法是使用查询 .eq() 函数查找特定的记录匹配。如果找到匹配的记录,则可以更新,否则继续插入。见下文。
这么快什么是promise?
通俗地说,将 Promise 想象成 FedEx 跟踪代码。
当你调用基于承诺的函数要求它做某事时,你会得到一个承诺,即你所要求的将完成,或者如果出现问题,你将被告知。
就像联邦快递跟踪代码一样 - 你不知道东西是否已经到达(你的功能已经完成了你想要的),除非你使用代码检查跟踪状态或者联邦快递送货车到达并且你收到包裹。此时跟踪代码会更新以表明包裹已送达,您可能会收到一条短信或电子邮件,说明包裹已送达。
Promise 函数要么成功完成并在 then 函数调用中得到结果,要么如果发生错误,则触发 catch() 事件。所以所有基于 Promise 的函数都类似于 if then else 条件测试,只是它们看起来像这样:
sendFedEx(package) // Call doesn't resolve immediately you have to wait for fedEx!
.then((fedExDeliveryInfo) => {
//Your package arrived!
})
.catch((fedExLostPackageInfo) => {
//Your package got lost :-(
});
在您的代码中,您在数据收集之外进行了不区分大小写的比较。对于大量数据收集,这可能会占用大量资源。更好的方法是存储不区分大小写的字符串:
(item.firstName + item.lastName).toLowerCase() 在数据记录中,然后使用 .eq 将其用于您的查询。这样你就可以让数据收集完成它的工作并简化你的代码。
注意:这利用了 beforeInsert() returns 承诺这一事实。
Syntax:
function beforeInsert(item: Object, context: HookContext): Promise
这里是给你的修改建议,有很多意见!
import wixData from "wix-data";
export function Memberships_beforeInsert(item, context) {
// Memberships_beforeInsert returns a promise. So does
// wixData.query...find() so we simply return it to maintain the Promise
// chain.
var compareName = (item.firstName + item.lastName).toLowerCase();
// Add a compareName column value to item for future querying
// This will be inserted into the data collection
item.compareName = compareName;
//-------------------------------------------------------//
// This is the head of the Promise chain we need to return
//-------------------------------------------------------//
return wixData.query(context.collectionName)
.eq('compareName', item.compareName) // Query the compareName
.find()
.then((res) => {
var members = res.items;
var len = res.length;
console.log(len);
// Should only have one record or no records otherwise we have a
// problem with this code :-)
// So if we have too many we throw and error. This will be caught in
// an outer catch if we have one
if (len > 1) {
throw Error(`Internal Error! Too many records for ${item.firstName} ${item.lastName}`);
}
// If we get here we have a valid record OR we need to return a result
// To do this we will use a return variable set to the item which
// assumes we will insert item. This will be overridden with the save
// Promise if we have a record already
var result = item;
if (len === 1) {
// We have a record already so we need to update it and return null
// to the caller of beforeInsert to halt the insert. This is a
// Simple case of adding the _id of the found record to the item we
// have been given.
item['_id'] = member._id;
// Again remember we are using promises so we need to return the
// wixData.update result which is a promise.
result = wixData.update(context.collectionName, toUpdate)
.then((savedRecord) => {
// Now we have chained the update to the beforeInsert response
// This is where we can tell the Insert function to abort by
// returning null.
return null;
});
}
// Now we can return the result we have determined to the caller
return result;
});
}
这应该可以完成您想要完成的工作。
我正在尝试验证对象是否已存在于 wix 集合中,以及它是否会取消对数据库的 inset() 调用
import wixData from "wix-data";
export function Memberships_beforeInsert(item, context) {
var name = item.firstName + item.lastName;
name = name.toLowerCase();
wixData.query(context.collectionName)
.find()
.then((res) => {
var members = res.items;
var len = res.length;
console.log(len)
for (var i = 0; i < len; i++) {
let member = members[i];
let memberName = member.firstName + member.lastName;
memberName = memberName.toLowerCase();
if (memberName === name) {
let toUpdate = {
'_id': member._id
}
wixData.update(context.collectionName, toUpdate)
return null;
}
return item;
}
});
//toHere
}
我对 wixCode 还很陌生,但我希望这会等到 .then() 被调用,然后 return 如下,但是由于 wixCode 使用承诺,代码会立即转到 //toHere
代码部分,它在其中找到 return 并取消调用。它将数据添加到数据库而不是 returning null.
好的,所以当我们查看您的代码时,您似乎想要找到与您尝试插入到会员资格的记录匹配的记录,然后中止插入并执行更新(如果存在)。更好的方法是使用查询 .eq() 函数查找特定的记录匹配。如果找到匹配的记录,则可以更新,否则继续插入。见下文。
这么快什么是promise?
通俗地说,将 Promise 想象成 FedEx 跟踪代码。
当你调用基于承诺的函数要求它做某事时,你会得到一个承诺,即你所要求的将完成,或者如果出现问题,你将被告知。
就像联邦快递跟踪代码一样 - 你不知道东西是否已经到达(你的功能已经完成了你想要的),除非你使用代码检查跟踪状态或者联邦快递送货车到达并且你收到包裹。此时跟踪代码会更新以表明包裹已送达,您可能会收到一条短信或电子邮件,说明包裹已送达。
Promise 函数要么成功完成并在 then 函数调用中得到结果,要么如果发生错误,则触发 catch() 事件。所以所有基于 Promise 的函数都类似于 if then else 条件测试,只是它们看起来像这样:
sendFedEx(package) // Call doesn't resolve immediately you have to wait for fedEx!
.then((fedExDeliveryInfo) => {
//Your package arrived!
})
.catch((fedExLostPackageInfo) => {
//Your package got lost :-(
});
在您的代码中,您在数据收集之外进行了不区分大小写的比较。对于大量数据收集,这可能会占用大量资源。更好的方法是存储不区分大小写的字符串: (item.firstName + item.lastName).toLowerCase() 在数据记录中,然后使用 .eq 将其用于您的查询。这样你就可以让数据收集完成它的工作并简化你的代码。 注意:这利用了 beforeInsert() returns 承诺这一事实。
Syntax:
function beforeInsert(item: Object, context: HookContext): Promise
这里是给你的修改建议,有很多意见!
import wixData from "wix-data";
export function Memberships_beforeInsert(item, context) {
// Memberships_beforeInsert returns a promise. So does
// wixData.query...find() so we simply return it to maintain the Promise
// chain.
var compareName = (item.firstName + item.lastName).toLowerCase();
// Add a compareName column value to item for future querying
// This will be inserted into the data collection
item.compareName = compareName;
//-------------------------------------------------------//
// This is the head of the Promise chain we need to return
//-------------------------------------------------------//
return wixData.query(context.collectionName)
.eq('compareName', item.compareName) // Query the compareName
.find()
.then((res) => {
var members = res.items;
var len = res.length;
console.log(len);
// Should only have one record or no records otherwise we have a
// problem with this code :-)
// So if we have too many we throw and error. This will be caught in
// an outer catch if we have one
if (len > 1) {
throw Error(`Internal Error! Too many records for ${item.firstName} ${item.lastName}`);
}
// If we get here we have a valid record OR we need to return a result
// To do this we will use a return variable set to the item which
// assumes we will insert item. This will be overridden with the save
// Promise if we have a record already
var result = item;
if (len === 1) {
// We have a record already so we need to update it and return null
// to the caller of beforeInsert to halt the insert. This is a
// Simple case of adding the _id of the found record to the item we
// have been given.
item['_id'] = member._id;
// Again remember we are using promises so we need to return the
// wixData.update result which is a promise.
result = wixData.update(context.collectionName, toUpdate)
.then((savedRecord) => {
// Now we have chained the update to the beforeInsert response
// This is where we can tell the Insert function to abort by
// returning null.
return null;
});
}
// Now we can return the result we have determined to the caller
return result;
});
}
这应该可以完成您想要完成的工作。