Я изучал и понял что результат команды find и findOne нельзя вернуть вне функции которая передаётся вторым аргументом в них.
Так вот можно вынуть только через Promise, я сделал вот такой код:
var ret = Account.findOne({
num: 256
});
ret.model['$init'].then(function(A) {
console.log(A); //выводит модель
}, function() {
console.log('fail');
});
Account это модель mongoose.
Так вот аргумент A выдаёт ту же самую модель, а другие аргументы промис не передаёт. Мне нужно вернуть найденный объект во внешнюю переменную чтоб с ним по нормальному работать
Асинхронные API (что на коллбеках что на промисах) так или иначе требуют от тебя объявить функцию, которая принимает данные для обработки (в твоем случае - объект пользователя) как аргумент. И этот коллбек передать асинхронному API.
Пример на коллбеках
function processUser(user) {
console.log('processing user', user)
}
Account.findOne({
num: 256
}, function (error, user) {
if (error) {
// handle error
return
}
processUser(user)
});
И на промисах
function processUser(userPromise) {
userPromise.then(function (user) {
console.log('processing user', user)
})
}
var userPromise = findOne({
num: 256
})
processUser(userPromise)
Если решения не подходят чтобы организовать обработку кода как ты хочешь, покажи как выгляит код обработки. Возможно он вносит такие ожидания от кода, которые невозможно реализовать на js.
Убедись что у тебя только 1 документ с полем num: 256 и что он есть в коллекции.
Ты запускаешь именно тот код который показываешь в комментарии?
Вывод user вовзращает:
Не вижу в коде где выводится user. Соответственно вопрос - как ты получил значение документа пользователя которое в комментарии?
Нельзя писать код так чтобы асинхронные функции манипулировали переменной в общей области видимости. Я про подход с var exist; По шкале от -5 до +5, где -5 - полный отстой решение, 0 - нейтральное решение и +5 - идеальное решение это решение на -3.5.
Та, функция, которой нужно знать о результате проверки должна предоставить функцию-коллбек. Нужно делать как в примере ниже.
Вот так выглядит проверка того что у пользователя в массиве arr есть элемент "item" с последующим рендером результата в темплейт (expressjs).
// Проверка что у пользователя в массиве `arr` есть элемент `"item"`
function checkHasItem(num, callback) {
Account.findOne({
num: num
}, function (error, user) {
if (error) {
callback(error)
return
}
if (user) {
callback(null, user.arr.indexOf('item') !== -1)
} else {
callback({message: 'No user with num ' + num})
}
});
}
// routes
app.get('/has-item', function (req, res) {
checkHasItem(req.params.num, function (err, userHasItem) {
if (err) {
res.render('error', {
error: err
})
} else {
res.render('index', {
userHasItem: userHasItem
})
}
})
})
Я заккоментировал потому что тот код приводит к ошибке, возвращаемый объект вообще не имеет в себе нужного массива arr
Код просто для примера, мне надо чтобы всё работало, а потом естественно я смогу справится и без переменных
Вот я написал подобный код:
function myCheck(num, callback) {
Account.findOne({
num: +num
}, function (err, user) {
if (err) {
callback(err);
return;
}
console.log(user);
if(user)
callback(null, user.arr.indexOf(num));
else
callback('Число не найдено');
});
}
router.get('/test/:num', function(req, res) {
myCheck(req.params.num, function(err, number) {
if(err)
res.send(err);
else
res.send('Число найдено. Находится в массиве по счёту: '+(number+1));
});
console.log('continue'); //и как же здесь предотвратить выполнение дальнейшего кода
// Здесь могут быть строки которые не должны вызыватся если число
// есть в базе данных
});
Но прошлая проблема так и не исчезла, на этот раз выходит немного другая ошибка: TypeError: Cannot read property ‘indexOf’ of undefined
Вторую проблему можно исправить цепочками вызовов, а вот первую никак.
И самое смешное то что console.log(Array.prototype.slice.call(user)); выдаёт пустой массив
Да это же ужасно почти все типы указывать, если у меня их там 500 то это вообще полная бредятина, нельзя просто по нормальному обратится к коллекции и работать с ней как в mongo.
Всё я сделал так