Then у промиса с промисом

Есть такой код:

funcPromise(id)
    .then(id => {
        addIdToDB(id, otherParams)
            .then(result_addIdToDB => {
                console.log("THEN AFTER THEN WITH PROMISE");
            }).catch(err => {
                console.log("CATCH AFTER THEN WITH PROMISE");
            });
    });

В нем есть две функции, funcPromise которая возвращает промис (котороый не резолве возвращает ид), и функция которая принимает ид и какие-то внешние параметры addIdToDB которая так же возвращает промис (и на ресолве выдает ответ добавилось ли ид в базу даных иначе вызывает reject с ошибкой нет). Но тут вторая функция вложена в результат ответа первой resolve первой функции, можно ли сделать что бы они были по порядку в then? По типу такого:

funcPromise(id)
    .then(id => addIdToDB(id, otherParams)
    .then(result_addIdToDB => {
         console.log("THEN AFTER THEN WITH PROMISE");
     })
    .catch(err => {
         console.log("CATCH AFTER THEN WITH PROMISE");
     });

Примерный код вызываемой функции:

function funcPromise(id) {
    return new Promise((res, rej) => {
           // action
           setTimeout(res(4), 2000);
       })
  }

}


Ответы (2 шт):

Автор решения: Aleksandr

С пoмoщью мeтoдa then(), вызывaeмoгo для промиса, мoжнo зapeгиcтpиpoвaть oбpaтный вызoв, кoтopый бyдeт cдeлaн пpи yдaчнoм выпoлнeнии промиса. В peзyльтaтe вызoвa мeтoдa then() тaкжe вoзвpaщaeтcя нoвый промис. Cлeдoвaтeльнo, ничтo нe мeшaeт Вaм cвязaть в цeпoчкy cтoлькo мeтoдoв then(), cкoлькo пoтpeбyeтcя. Первый вызов then() становится первым шагом асинхронной последовательности, а второй вызов then() — ее вторым шагом. Все это может продолжаться так долго, как потребуется. Просто продолжайте присоединять вызовы к предыдущим then() с каждым автоматически созданным промисом.
Не забудьте в конце цепочки использовать catch() для отлавливания ошибок. В коде вопроса ошибки функции funcPromise не будут пойманы.

funcPromise(id)
  .then(addIdToDB(result_of_funcPromise, otherParams))
  .then(result_of_addIdToDB => {
    сonsole.log("THEN AFTER THEN WITH PROMISE") })
  .catch(err => {
    console.log("CATCH AFTER THEN WITH PROMISE") });
→ Ссылка
Автор решения: Eugene X

Вообщем в трех словах как работает код промиса в примере на гитхаб на примере склада.

https://github.com/akinmaurice/node-express-forum/blob/master/controllers/appController.js

Предположим у нас есть работник склада - у него куча больших коробок и тут он берется за коробку с надписью "getIndexPage" но наш работник заранее знает что в большой коробке есть много маленьких коробок потому что мы ему об этом написали ключевым словом async.

exports.getIndexPage = async (req, res) => {

Он открывает большую коробку и видит там 2 коробки поменьше Post.find и Post.count. Эти коробки надо открыть в приоритете пока работаешь с большой коробкой getIndexPage на что нам указывают ключевые слова - await.

const postsPromise = await Post.find(). ...
const countPromise = await Post.count()

следующий шаг await Promise.all. Фактический полностью запрещает нашему работнику работать с коробкой getIndexPage пока он не распакует две более маленьких коробочки.

const [posts, count] = await Promise.all([postsPromise, countPromise]);

Так вот, если вдруг нашего работника склада вдруг отвлекут на работу с другой большой коробкой, то после работы с другой большой коробкой, то он не пойдет лезть в коробку getIndexPage, и даже не будет дергать большую коробку. Он сразу пойдет распаковывать 2 маленький коробочки пока не достанет из них результат.

И только после этого вернеться к коробке getIndexPage. Сняв флаг блокировки с Promise.all и перенеся результаты в [posts и count]

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

→ Ссылка