Что не так с решением обещания?

Любые идеи? Почему node говорит 'filename undefined'? Благодарю. Контракт, функции политики и счета-фактуры разрешаются без данных, просто разрешите().

var dc = function(data) {

return new Promise(function(resolve, reject) {

    var filename = 'Test';

    var contract = function() { ... }

    var policy = function() { ... }

    var invoice = function() { ... }

    contract().then(invoice().then(policy().then(function() {
        console.log(filename); // Test
        resolve(filename); // UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): ReferenceError: filename is not defined
    })))
})

}

Ответ 1

Прежде всего, вы не можете писать:

contract().then(invoice() ... )

(это будет работать, если функция invoice() возвращает другую функцию в качестве обработчика then)

Вам нужно написать:

contract().then(function (value) { invoice() ... })

Или:

contract().then(value => invoice() ... )

Или, может быть, это, если одна функция должна обрабатывать результат другой функции:

contract().then(invoice).then(policy).then(function (result) { ... });

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

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

2017 Обновление

Если вы используете ES2017 async/wait, доступный в Node с версии v7.0, а вместо:

contract().then(invoice).then(policy).then((result) => { ... });

вы можете использовать:

let a = await contract();
let b = await invoice(a);
let c = await policy(b);
// here your `result` is in `c`

или даже это:

let result = await policy(await invoice(await contract()));

Обратите внимание, что вы можете использовать его только в функциях, объявленных с помощью ключевого слова async. Это работает с Node с версии 7. Для более старых версий Node вы можете использовать аналогичную вещь с немного другим синтаксисом, используя сопрограммы на основе генератора, или вы можете использовать Babel для перевода вашего кода, если это то, что вы предпочитаете, если что вы уже делаете.

Это довольно новая функция, но в ней много вопросов о переполнении стека. См:

Ответ 2

Похоже, вы не заботитесь о заказе, и в этом случае вы можете использовать Promise.all. Это работает для вас? Он будет разрешаться после того, как все promises будут разрешены, или он отклонит, как только кто-либо из них отклонит.

function contract(data) { return new Promise(...) }
function policy(data) { return new Promise(...) }
function invoice(data) { return new Promise(...) }

function dc(data) {
  var filename = 'Test';
  return new Promise(function(resolve, reject) {
    Promise.all([contract(data), policy(data), invoice(data)]).then(
      function (values) {
        console.log(filename);
        resolve(filename)
      },
      function (err) {
        reject(err);
      }
    );
  });
}

Если вы заботитесь о заказе, вам нужно связать их, как вы пытались сделать. Вы передаете код promises как аргумент then. Вам необходимо передать функции.

function contract(data) { return new Promise(...) }
function policy(data) { return new Promise(...) }
function invoice(data) { return new Promise(...) }

function dc(data) {
  var filename = 'Test';
  return new Promise(function(resolve, reject) {
    contract(data).then(
      function (contract_res) {
        policy(data).then(
          function (policy_res) {
            invoice(data).then(
              function (invoice_res) {
                console.log(filename);
                resolve(filename);
              },
              function (err) { reject(err); } // invoice promise rejected
            );
          },
          function (err) { reject(err); } // policy promise rejected
        );
      },
      function (err) { reject(err); } // contract policy rejected
    );
  });
}

Вы можете упростить это с помощью catch, но глубокая вложенность - это боль. Взгляните на этот пост о уплощение цепей обещаний.