Протокол и мультиметоды являются взаимодополняющими и предназначены для немного разных вариантов использования.
В общем, мой совет - использовать протоколы, если у вас нет конкретного случая, требующего многоточия.
Случай, когда вы можете потребовать многоточие, выглядит примерно так:
(defn balance-available? [amount balance] (> balance amount))
(defmulti withdraw balance-available?)
(defmethod withdraw true [amount balance]
(- balance amount))
(defmethod withdraw false [amount balance]
(throw (Error. "Insufficient balance available!")))
Обратите внимание, что вы не можете использовать протоколы здесь по обоим причинам:
Редактировать: Исправлено путем добавления «[this.userID]» после каждого «пользовательского» вызова.
Я опробовал ваш метод, и всякий раз, когда я записываю данные, создается новый тег eTag, который приводит к разделению объекта:
"document": {
"25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
"25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
"25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
"25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
"25781dc4-805d-4e69-bf89-da1f4d72e7cb": {
"name": "",
"age": "",
"gender": "",
"education": "",
"major": "",
"eTag": "\"00003998-0000-0000-0000-5c797fff0000\""
},
"name": "Jane Doe",
"eTag": "\"00003e98-0000-0000-0000-5c7980080000\""
},
"age": 22,
"eTag": "\"00004898-0000-0000-0000-5c7980150000\""
},
"gender": "female",
"eTag": "\"00004d98-0000-0000-0000-5c79801b0000\""
},
"education": "Bachelor",
"eTag": "\"00005498-0000-0000-0000-5c7980200000\""
},
"major": "Business Administration",
"complete": true
Как я могу предотвратить это?
Мой Код:
В конструкторе:
this.changes = {};
this.userID = "";
this.userDatax = {
name: "",
age: "",
gender: "",
education: "",
major: "",
eTag: '*',
}
В диалогах:
async welcomeUser (step) {
console.log("Welcome User Dialog");
//step.context.sendActivity({ type: ActivityTypes.Typing});
// Initialize UserData Object and save it to DB
this.changes[this.userID] = this.userDatax;
await this.memoryStorage.write(this.changes);
}
async promptForAge (step) {
console.log("Age Prompt");
// Read UserData from DB
var user = await this.memoryStorage.read([this.userID]);
console.log(user);
// Before saving entry, check if it already exists
if(!user.name) {
user.name = step.result;
user.eTag = '*';
// Write userData to DB
this.changes[this.userID] = user;
await this.memoryStorage.write(this.changes);
}
}
Поскольку идентификаторы хранилища (см. Изображение) создаются автоматически на основе идентификаторов пользователей (которые также могут создаваться автоматически и зависят от канала) и идентификаторов каналов, это может быть очень сложно сделать. Это может затруднить сохранение данных о пользователях и разговорах, особенно по ботам и каналам.
Пример ID:
Подробнее о работе идентификаторов .
Лично я бы написал свое собственное хранилище вместо (или в дополнение к) сохранения его с помощью UserState
.
Чтобы записать свои данные, сделайте что-то вроде этого:
const changes = {};
const userDataToWrite = {
name: step.result,
eTag: '*',
}
// Replace 'UserId' with however you want to set the UserId
changes['UserId'] = userDataToWrite;
this.memoryStorage.write(changes);
Это сохранит документ, который выглядит следующим образом (я установил 'UserId' в 'user123':
Читать:
const userDataFromStorage = await this.memoryStorage.read(['UserId']);
userDataFromStorage
будет выглядеть так:
{ UserId:
{ name: 'myName',
eTag: '"0000c700-0000-0000-0000-5c7879d30000"' } }
Вам придется управляйте пользовательскими идентификаторами самостоятельно, но это обеспечит возможность чтения данных между ботами, каналами и пользователями.