优化嵌套承诺

时间:2016-10-21 09:51:36

标签: javascript node.js es6-promise

如何优化以下内容(即避免嵌套承诺)?它有效,但似乎我将继续嵌套承诺

代码首先验证并返回一个服务,然后它将该服务提供给一个异步调用api来获取项目的函数,然后我会对这些项目执行某些操作,可能会调用另一个包含异步调用的函数: / p>

new Promise(function(resolve, reject) {
    auth.authenticate(resolve);
}).then(function(service) {
    console.log('service', service);
    new Promise(function(resolve, reject) {
        lineItems.getLineItems(service, resolve, reject);
    }).then(function(items) {
        console.log('returned line items');
        console.log(items);
    }).catch(function(err){
        console.log('error!', err);
    });
});

2 个答案:

答案 0 :(得分:1)

只需从then返回新承诺:

new Promise(function(resolve, reject) {
    auth.authenticate(resolve);
}).then(function(service) {
    console.log('service', service);
    return new Promise(function(resolve, reject) {
        lineItems.getLineItems(service, resolve, reject);
    });
}).then(function(items) {
    console.log('returned line items');
    console.log(items);
}).catch(function(err){
    console.log('error!', err);
});

此外,如果您可以调整lineItems.getLineItems以返回承诺,它看起来更简洁:

new Promise(function(resolve, reject) {
    auth.authenticate(resolve);
}).then(function(service) {
    console.log('service', service);
    return lineItems.getLineItems(service);
}).then(function(items) {
    console.log('returned line items');
    console.log(items);
}).catch(function(err){
    console.log('error!', err);
});

答案 1 :(得分:1)

我发现主要关于函数定义方式的几个问题。这实际上来自代码中定义的异步函数的非标准签名。

如果您写了auth.authenticatelineItems.getLineItems,请更新这些函数以返回正确的Promise。然后组成将是:

auth.authenticate()
    .then((service) => lineItems.getLineItems(service))
    .then((items)   => console.info('Items:',items))
    .catch((err)    => console.error(err));

如果auth.authenticate和/或lineItems.getLineItems是外部的,并遵循标准的nodejs callbak / errback样式,则可以包装这些函数以返回一个promise:

const authenticate = Promise.promisify(auth.authenticate, {context:auth});
const getLineItems = Promise.promisify(lineItems.getLineItems,{context:lineItems});

authenticate()
    .then(getLineItems)
    .then((items)   => console.info('Items:',items))
    .catch((err)    => console.error(err));