Результат возврата обещаний вместо Promise в Nodejs

Фон

Я пытаюсь изучить promises, и у меня есть цепочка обещаний, которую я хочу улучшить.

Проблема

Изучая цепочку promises, я не понимаю, почему кто-то скорее вернет обещание вместо того, чтобы вернуть его значение.

Возьмем следующий пример, в котором используется цепочка суждений:

let myObj = new MyClass();

myObj.getInfo()
    .then(result => writeOutput(FILE_NAME, result))
    .then(console.log(FILE_NAME + " complete"))
    .catch(error => console.error(error));

class MyClass{

    getInfo() {
        return new Promise(function(fulfil, reject) {
            fulfill("I like bananas");
        });
}

Здесь мне нужно цепью 2 раза. Но если бы я должен был прямо вернуть результат из метода getInfo() вместо того, чтобы возвращать Promise, я мог бы сделать что-то вроде следующего:

let myObj = new MyClass();

let str = myObj.getInfo();

writeOutput(FILE_NAME, str)
    .then(console.log(FILE_NAME + " complete"))
    .catch(error => console.error(error));

Вопросы

Итак, как вы можете видеть, я немного смущен.

  • Учитывая, что getInfo() на самом деле async, возможно ли получить аналогичный код с кодом в моем втором примере кода?
  • Если бы это было возможно, было бы хорошей идеей? Как вы это сделаете?

Ответ 1

Вы можете вернуть значение только из некоторой функции, если это значение сразу доступно при вызове этой функции (в том же тике цикла события). Помните, что return является синхронным.

Если он недоступен сразу же, вы можете вернуть обещание (или вы можете использовать обратный вызов, но здесь вы конкретно спрашиваете о promises).

Более подробное объяснение см. в этом ответе, который я написал некоторое время назад на вопрос о том, как вернуть результат вызова AJAX из некоторой функции. Я объяснил, почему вы не можете вернуть значение, но вы можете вернуть обещание:

Вот еще один ответ, связанный с этим: он почему-то потерялся, но я думаю, что он объясняет аналогичную проблему, о которой вы спрашиваете о ней:

Ответ 2

Я не понимаю, почему кто-то скорее вернет обещание вместо того, чтобы вернуть его значение.

Потому что у вас еще нет значения.

Учитывая, что getInfo() на самом деле является async, возможно ли получить аналогичный код с кодом в моем втором примере кода?

Если он асинхронен, он должен вернуть обещание.

Синтаксис, который позволяет избежать вызовов then (но все еще использует и производит promises), становится возможным благодаря async/await:

async function writeInfo(FILE_NAME) {
    const myObj = new MyClass();
    try {
        const str = await myObj.getInfo();
        await writeOutput(FILE_NAME, str);
        console.log(FILE_NAME + " complete");
    } catch (error) {
        console.error(error);
    }
}
writeInfo("…");

Ответ 3

Цель обещания - сказать: "Данные будут там когда-нибудь, просто продолжайте с вашей кодировкой на данный момент", так что ваша страница не застрянет, например. В основном вы используете Promises, например, для загрузки чего-либо с сервера.

Ответ 4

Еще один способ взглянуть на первый вопрос ( "зачем кому-нибудь..." ):

Когда вы вызываете .then или .catch по обещанию, ожидающее обещание, возвращенное из вызова, добавляется к концу существующей цепочки обещаний. (Разрешение "существующей цепочки" может содержать только одно обещание).

Когда вы разрешаете (а не "выполняете", вы не можете выполнить обещание с обещанием) обещание с обещанием, обещание, используемое в разрешении, вставляется во главу того, что остается в цепочке обещаний.

Обещание, используемое в разрешении, должно выполняться со значением перед тем, как вызывается следующее предложение .then или .catch в цепочке.