Mongoose всегда возвращает обещание [dубликат]

У меня есть обещание, которое возвращает данные, и я хочу сохранить их в переменных.

Могу ли я каким-то образом использовать это (например, обернуть его с помощью async / await):

const { foo, bar } = Promise.then(result => result.data, errorHandler);
// rest of script

Могу ли я каким-то образом использовать это (например, обернуть его с помощью async / await):

Promise.then(result => {
   const { foo, bar } = result.data;
   // rest of script
 }, errorHandler);

Примечание: вместо встроенной реализации используется библиотека Bluebird, а я не может измениться с Promise на asnyc / wait или Generators.

10
задан 28 April 2016 в 13:21

1 ответ

Хотя вы можете получить значение от ожидаемого Promise внутри функции async (просто потому, что он приостанавливает функцию для ожидания результата), вы никогда не сможете получить значение непосредственно из Promise и вернуться в ту же область, что и Само обещание.

Это потому, что «из» означало попытку взять что-то, что существует в будущем (окончательно разрешенное значение) и помещать его в контекст (синхронное назначение переменных), который уже произошел в прошлом.

То есть, путешествие во времени. И даже если бы время было возможным, это, вероятно, не было бы хорошей практикой кодирования, потому что путешествие во времени может быть очень запутанным. :)[!D3]

В общем, если вы чувствуете, что вам нужно это делать , это хороший признак того, что вам нужно что-то реорганизовать. Обратите внимание, что то, что вы делаете с «result => result.data» здесь:

Promise.then(result => result.data, errorHandler);
// rest of script

.. - это , уже имевшееся в прошлом случай работы с ( буквально, переписывая) значение, передавая его функции. Но, предполагая, что «// остальная часть скрипта» делает что-то важное, связанное с этим значением, вы, вероятно, захотите продолжить сопоставление по обновленному значению с помощью еще одной функции, которая затем делает что-то побочное действие-y со значением (например, отображать данные на экране).

Promise
    .then(result => result.data)
    .then(data => doSomethingWithData)// rest of script
    .catch(errorHandler);

«doSomethingWithData» будет называться ( continue , который он когда-либо называл) в какой-то неизвестной точке в будущем. Вот почему это хорошая практика, чтобы четко инкапсулировать все это поведение в определенную функцию, а затем перехватить эту функцию до цепочки Promise.

Это честно лучше, потому что это требует от вас четкого объявления определенной последовательности событий, которые произойдут, явно отделяются от первого запуска всего исполнения вашего кода приложения.

Другими словами, представьте этот сценарий, предположительно выполненный в глобальной области верхнего уровня:

const { foo, bar } = Promise.then(result => result.data, errorHandler);
console.log(foo);
//...more program

Что бы вы ожидали увидеть там? Есть две возможности, и обе они плохие.

Вся ваша программа (console.log и все, что происходит после нее) должна была остановить и ждать выполнения обещания, прежде чем он сможет узнать, что " foo "было бы ... нет, может быть. (это то, что «ждет» внутри функции async, действительно делает: он приостанавливает всю функцию до тех пор, пока не вернется значение или ошибка). foo и bar просто не определены (это то, что на самом деле происходит), поскольку, поскольку выполняемые синхронно, они просто были бы несуществующими свойствами объекта Promise (который не является значением, но Monad обертывает возможное значение ИЛИ ошибку), которое, скорее всего, даже не содержит значения.
1
ответ дан 15 August 2018 в 16:01

Другие вопросы по тегам:

Похожие вопросы: