Что плохого в разрешении обещаний?
Есть идеи? Почему узел говорит "имя файла не определено"? Благодарю. Функции контракта, политики и счета-фактуры разрешаются без данных, просто выполните разрешение ().
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
})))
})
}
2 ответа
Прежде всего, вы не можете написать:
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/await, который доступен в 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 для переноса кода, если вы предпочитаете это, если это то, что вы уже используете. делать.
Это довольно новая функция, но есть много вопросов по переполнению стека по этому поводу. Увидеть:
- попробуйте / поймать блоки с асинхронным / ожиданием
- Есть ли асинхронная блокировка программным языком?
- попробуйте / поймать блоки с асинхронным / ожиданием
- Используйте ожидание вне асинхронного
- Использование acyns/await в Node 6 с Babel
- Когда генерируются асинхронные методы и как вы их ловите?
- использование обещаний в node.js для создания и сравнения двух массивов
- Сохранение цепочек обещаний
- функция будет возвращать ноль из javascript post/get
Похоже, вы не заботитесь о заказе, и в этом случае вы можете использовать Promise.all. Это работает для вас? Он разрешится, как только будут выполнены все обещания, или отклонит их, как только одно из них отклонит.
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);
}
);
});
}
Если вы заботитесь о заказе, то вам нужно их приковать, как вы пытались это сделать. Ваш код передает обещания в качестве аргумента 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
Но глубокое вложение - это боль. Взгляните на этот пост о сплющивании цепей Promise.