Mongoose: Добавить возвращаемое значение «обещание» в операцию сохранения модели

Созданный на 16 апр. 2013  ·  50Комментарии  ·  Источник: Automattic/mongoose

Добавлена ​​поддержка возврата обещания для сохранения операции, в настоящее время возвращает неопределенное значение. Существует несколько путей возврата в зависимости от проверки и состояния сохранения, которые необходимо обновить. Это позволит объединить несколько операций сохранения с помощью .then() вместо вложения.

enhancement

Самый полезный комментарий

На данный момент я делаю это:

userSchema.methods.saveAsync = function() {
  return new Promise((resolve,reject) => {
    this.save((err) => {
      if(err) return reject(err)
      resolve()
    })
  })
}

Все 50 Комментарий

Я добавляю это в список для 4.x. Относится к тому, как реализовано промежуточное ПО (hooks.js).

Потрясающе, спасибо. Я реализовал версию jquery .when как расширение объекта обещания мангуста для моего проекта. Вам было бы интересно получить пулл-реквест для этого?

var p1 = Users.find();
var p2 = Животные.find();
Promise.when(p1, p2).addBack(функция(ошибка, пользователи, животные) {
//и т.д
});

Нет, спасибо. Я действительно не хочу добавлять дополнительные функции, которые можно реализовать вне мангуста. Оно уже раздуто.

Для тех, кто нашел эту тему, вот она: https://github.com/wshaver/mongoosewhen

@wshaver публикует это в npm и добавляет тег мангуста, чтобы он отображался на http://plugins.mongoosejs.com.

Перемещено сюда, чтобы соответствовать использованию дефисов в имени другого плагина Mongoose: https://github.com/wshaver/mongoose-when

Опубликовано в npm, помечено. Пока не появляюсь, но, возможно, есть задержка.

@wshaver круто. обновляется раз в сутки.

Покопавшись в # 1446, я думаю, что смогу добиться этого, не удаляя «hooks.js».
Зеленый свет?

Действуй

В понедельник, 7 октября 2013 г., Рафаэль Акерманн написал:

После изучения # 1446 https://github.com/LearnBoost/mongoose/issues/1446 я думаю, что смогу добиться этого, не удаляя «hooks.js».
Зеленый свет?


Ответьте на это письмо напрямую или просмотрите его на Gi tHubhttps://github.com/LearnBoost/mongoose/issues/1431#issuecomment -25792310
.

Аарон
@ааронхекманн https://twitter.com/#!/ааронхекманн
soundcloud.com/ajhecky
github.com/aheckmann

Большой пиар готов

Мне бы это тоже очень помогло. Должна быть возможность вызвать myDoc.save().exec() - поэтому в основном save должен возвращать запрос, который может быть выполнен. Или в чем причина того, что Save не возвращает Query?

+1 за возврат обещания, если мы опустим обратный вызов

Исправление находится в ветке master , которую планируется включить в 3.10.

Включает ли это возвращенное обещание для операции создания модели?

@GDownes create() уже возвращает обещание :) http://mongoosejs.com/docs/api.html#model_Model.create

любая запланированная дата выпуска 3.10? :)

@swayf 4.0 выйдет еще через несколько месяцев. Моя очередь на песке 2 сентября, но надеюсь раньше :)

Это все еще запланировано для следующей версии?

Да, это будет в версии 4.0, однако дата выхода пока неизвестна. Последняя оценка не совсем верна :(

:+1:

+1 потому что:

Мне нужно сохранить 2 документа в тесте мокко перед ловушкой, и эта функция позволит мне выполнить обратный вызов done() после сохранения обеих моделей.

Я попытался использовать метод Collection.insert([docs], done) , но он не запускает логику Schema.pre('save') , которая мне нужна для хеширования некоторых значений.

@arathael , вы всегда можете использовать асинхронный модуль, чтобы сохранить два ваших документа в async.parallel и выполнить в обратном вызове

Спасибо, чувак, я на самом деле тестирую это сейчас. Я просто вскочил, потому что я думаю, что встроенная поддержка от ODM будет отличной.

+1

Я использую экспериментальный ES7 await/async с использованием 6to5. Если record.save() вернул обещание, я могу сделать это:

try {
  await record.save()
} catch(err) {
  ...
}

На данный момент я делаю это:

userSchema.methods.saveAsync = function() {
  return new Promise((resolve,reject) => {
    this.save((err) => {
      if(err) return reject(err)
      resolve()
    })
  })
}

+1 для @aaronshaf , у меня отлично работает, я бы написал это также в ES5 для тех, кто не использует ES6. Спасибо

Вот что я сделал на данный момент. Очевидно, Q не нужен, но это то, что я использую для промисов в другом месте.

/*
 * Hack until mongoose 3.10 comes out. See this: https://github.com/LearnBoost/mongoose/issues/1431
 */
mongoose.Document.prototype.savePromise = function () {
    var that = this;
    return Q.Promise(function(resolve, reject) {
        that.save(function (err, item, numberAffected) {
            if (err) {
                reject(err);
            }
            resolve(item, numberAffected);
        });
    });
};

mongoose.Document.prototype.removePromise = function () {
    var that = this;
    return Q.Promise(function(resolve, reject) {
        that.remove(function (err, item) {
            if (err) {
                reject(err);
            }
            resolve(item);
        });
    });
};

+1 к взлому @jhullfly, однако я думаю, что разрешение Q принимает только один аргумент, поэтому numberAffected отбрасывается, нужно поместить их в массив или что-то еще, чтобы получить доступ к обоим:

mongoose.Document.prototype.savePromise = function () {
    var that = this;
    return Q.Promise(function(resolve, reject) {
        that.save(function (err, item, numberAffected) {
            if (err) {
                reject(err);
            }
            resolve([item, numberAffected]);
        });
    });
};

1+ за обещание, возвращаемое из сохранения!

Теперь save возвращает обещание в 4.0.1. Ваше здоровье.

+1

@arathael +1

Есть ли документация, связанная с тем, как save используется с промисами?

Я попробовал следующее, и это, похоже, не сработало:

var User = mongoose.model('User');
var u = new User();
u.save().then(function() {
// never gets here.
});
// I even tried the following, and neither works.
u.save().then(function() {}).end();

Вы используете mongoose 4.0.1 и установили ли вы его с помощью npm?

@Ouwen Да, я использую 4.0.1, и да, я это сделал, иначе я получил бы ошибку, если бы мангуст не был установлен.

Проблема в том, что then никогда не вызывается. Я почти уверен, что делаю что-то странное (иначе были бы быстро зарегистрированы ошибки), но я не могу объяснить, что именно, мне любопытно посмотреть, есть ли какие-либо примеры/документация вокруг этого.

Хм, очень странно. Я знаю, что у меня была версия 3.8.8, и я забыл установить npm, чтобы обновить ее до версии 4.0.1, поэтому обещание не было возвращено из u.save().

То, что вы написали, должно работать.

@limianwang успешно ли вы подключаетесь к серверу mongodb? Можете ли вы предоставить мне отдельный пример, который воспроизводит это?

Кажется, что объект обещания, возвращаемый .save(), не совпадает с другими обещаниями, он имеет catch/caught вместо onReject.

мангуст 4.1.10 и...

var u = new User();
u.save().then(...)

все еще не возвращает обещание

@xrado, пожалуйста, приведите более существенный пример. У нас есть тесты, чтобы показать, что это должно работать в mongoose 4.1.10.

@vkarpov15 мой плохой, я попробовал еще раз и работает .. я не знаю, что я делал раньше .. извините

У меня такая же проблема, Save сразу сохраняет данные в db и не вызывает код в then. Странно то, что у меня был еще один фрагмент кода, который вызывал блок then, и обещание сработало.

Код (часть user.save() сохраняет его, затем не определяется, но никогда не вызывается)

user.save().then( function(userX) { // сохранение работает
console.log(2); // это не вызывается
}).end() // не вызывается
.тогда (не определено, функция (ошибка) {
console.log('ошибка:' + ошибка); // не вызывается
});

Обновление, которое я использовал по-старому, и оно работает так:

user.save (функция (ошибка, новый пользователь) {
если (ошибка) console.log('err=' + err);
console.log('пользователь сохранен');
});

WTF: решение состояло в том, чтобы просто изменить версию мангуста на ^ 4.1.9 с «3.8.X».

Затем user.save().then( function(userX) { // сохранение работает
console.log(2);
}).конец()
.тогда (не определено, функция (ошибка) {
console.log('ошибка:' + ошибка);
});

РАБОТАЕТ!!!!!!!!!!! сладкий....

@nickjohngray рад, что вы это поняли :) Я настоятельно рекомендую вам прочитать руководство по обещаниям в документации, прежде чем продолжать использовать обещания с мангустом - не волнуйтесь, это короткое чтение.

У меня та же проблема... Я очень надеюсь, что мне не придется понижать весь основной выпуск только для того, чтобы сохранение работало внутри обещания.

@ jhyland87 jhyland87, пожалуйста, предоставьте образцы кода, чтобы я мог понять, в чем проблема.

@vkarpov15 Да , в билете

Это было исправлено в другом билете...

В основном, этот код:

var User = mongoose.model('User');
var u = new User();
u.save().then(function() {
// never gets here.
});

Просто нужно было добавить return при сохранении документа.. так что:

var User = mongoose.model('User');
var u = new User();
return u.save().then(function() {
// never gets here.
});

@ jhyland87 , к вашему сведению — еще один пример связывания обещаний с Mongoose .

Это все еще проблема?

У меня есть следующий код (с использованием TypeScript)...

User.findById(id)
.exec()
.then((user) => {
  user.name = 'new name from wherever!';
  return user.save();
})
.then((user) => {
  // want to do more stuff with the user object once it has been saved successfully...
  // ... but it never makes it here!!!
};

Однако, когда я добавляю пустой обратный вызов в функцию save() , все выглядит хорошо, как показано ниже...

User.findById(id)
.exec()
.then((user) => {
  user.name = 'new name from wherever!';
  return user.save(() => {
    // unwanted empty callback... hmmm?
  });
})
.then((user) => {
  // we made it here!!! but now...
  // user === undefined :(
};

Вы используете mpromise? Попробуйте переключиться на mongoose.Promise = global.Promise;

Была ли эта страница полезной?
0 / 5 - 0 рейтинги