Sails' Model.findOrCreate to return for 循环中的查询结果
Sails' Model.findOrCreate to return the query result in a for loop
我从前端收到一组项目名称 itemsNames
。我检查这些项目是否已经在数据库中或应该创建新记录。我写了下面的 for 循环。我希望循环 await
直到执行每个查询,并且 return 每个项目到列表中以便稍后执行更多过程。如果我删除 .exec() 方法,查询 return 是创建或找到的项目。如何公开创建的项目并让 for 循环等待直到检查每个注册表?我想拥有已创建或已存在项目的注册表。在以下示例屏幕截图中,所有项目都是新的。
for 循环:
let dbList;
for (var i = 0; i < itemsNames.length; i++) {
let itemsNames= itemsNames[i];
dbList+= await Item.findOrCreate({ name: itemsNames}, { name: itemsNames})
.exec( (err, item, wasCreated) => {
if (err) {
throw 'Unavailable';
}
if(wasCreated) {
sails.log('Created a new Item: ' + item.name);
} else {
sails.log('Found the existing Item: ' + item.name);
}
return item;
});
console.log('returned from findOrCreate Items: ' + i + ' ' + dbList);
}
console.log('Loop end');
return dbList;
这是控制台输出:
我正在使用 Sails 1.2.4
因为 findOrCreate
不接受数组作为参数,您确实需要遍历每个项目。最好使用 async module. Also mentioned here.
要在项目根目录中安装 async 运行 npm i async --save
。
然后您可以 const async = require('async');
或者您可以通过修改 config/globals.js
将其添加为全局模块。在 globals.js
中将 async: false,
更改为 async: require('async'),
。
这是一个简单的 async.map 代码,可以满足您的需求:
async.map(
items, // your items array [{"name": "foo"}, {"name": "bar"}, ...]
(item, cb) => Item
.findOrCreate(item, item)
.exec((err, item, created) => cb(err, {item, created})),
(err, data) => console.log(err || data) // data will contain array of data in {item: Item, created: true/false} format
);
如果您希望将此功能添加到控制器操作中,这里有一个示例:
findOrCreateMultiple(req, res) {
async.map(
req.param('items'),
(item, cb) => Item
.findOrCreate(item, item)
.exec((err, item, created) => cb(err, {item, created})),
(err, data) => {
if (err) return res.serverError(err);
res.json(data);
}
);
}
您发送:
{
"items": [{"name": "foo"}, {"name": "bar"}, {"name": "biz"}]
}
foo 和 bar 已经存在,biz 已创建。
回应:
[
{
"item": {
"createdAt": 1589379855770,
"updatedAt": 1589379855770,
"id": 1,
"name": "foo"
},
"created": false
},
{
"item": {
"createdAt": 1589379855774,
"updatedAt": 1589379855774,
"id": 2,
"name": "bar"
},
"created": false
},
{
"item": {
"createdAt": 1589380146471,
"updatedAt": 1589380146471,
"id": 3,
"name": "biz"
},
"created": true
}
]
我从前端收到一组项目名称 itemsNames
。我检查这些项目是否已经在数据库中或应该创建新记录。我写了下面的 for 循环。我希望循环 await
直到执行每个查询,并且 return 每个项目到列表中以便稍后执行更多过程。如果我删除 .exec() 方法,查询 return 是创建或找到的项目。如何公开创建的项目并让 for 循环等待直到检查每个注册表?我想拥有已创建或已存在项目的注册表。在以下示例屏幕截图中,所有项目都是新的。
for 循环:
let dbList;
for (var i = 0; i < itemsNames.length; i++) {
let itemsNames= itemsNames[i];
dbList+= await Item.findOrCreate({ name: itemsNames}, { name: itemsNames})
.exec( (err, item, wasCreated) => {
if (err) {
throw 'Unavailable';
}
if(wasCreated) {
sails.log('Created a new Item: ' + item.name);
} else {
sails.log('Found the existing Item: ' + item.name);
}
return item;
});
console.log('returned from findOrCreate Items: ' + i + ' ' + dbList);
}
console.log('Loop end');
return dbList;
这是控制台输出:
我正在使用 Sails 1.2.4
因为 findOrCreate
不接受数组作为参数,您确实需要遍历每个项目。最好使用 async module. Also mentioned here.
要在项目根目录中安装 async 运行 npm i async --save
。
然后您可以 const async = require('async');
或者您可以通过修改 config/globals.js
将其添加为全局模块。在 globals.js
中将 async: false,
更改为 async: require('async'),
。
这是一个简单的 async.map 代码,可以满足您的需求:
async.map(
items, // your items array [{"name": "foo"}, {"name": "bar"}, ...]
(item, cb) => Item
.findOrCreate(item, item)
.exec((err, item, created) => cb(err, {item, created})),
(err, data) => console.log(err || data) // data will contain array of data in {item: Item, created: true/false} format
);
如果您希望将此功能添加到控制器操作中,这里有一个示例:
findOrCreateMultiple(req, res) {
async.map(
req.param('items'),
(item, cb) => Item
.findOrCreate(item, item)
.exec((err, item, created) => cb(err, {item, created})),
(err, data) => {
if (err) return res.serverError(err);
res.json(data);
}
);
}
您发送:
{
"items": [{"name": "foo"}, {"name": "bar"}, {"name": "biz"}]
}
foo 和 bar 已经存在,biz 已创建。 回应:
[
{
"item": {
"createdAt": 1589379855770,
"updatedAt": 1589379855770,
"id": 1,
"name": "foo"
},
"created": false
},
{
"item": {
"createdAt": 1589379855774,
"updatedAt": 1589379855774,
"id": 2,
"name": "bar"
},
"created": false
},
{
"item": {
"createdAt": 1589380146471,
"updatedAt": 1589380146471,
"id": 3,
"name": "biz"
},
"created": true
}
]