首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >试着在承诺中抓住机会

试着在承诺中抓住机会
EN

Stack Overflow用户
提问于 2016-06-23 13:15:05
回答 3查看 4.9K关注 0票数 2

我需要编写一个返回承诺的函数,其中首先调用一个返回某些结果的同步函数A()。然后返回函数B(结果),其中B是接受A()结果的承诺。如果任何一个函数失败,我希望调用相同的错误函数C( error ),其中C是一个承诺。写这篇文章的最佳方式是什么。这是我所拥有的,但我认为有明显的方式我错过了。

代码语言:javascript
复制
function() {
    try {
        var result = A();
        return B(result)
            .catch(function(error) {
                return C(error);
            });
     }
     catch(error) {
         return C(error);
     }
}

将同步尝试和捕获与承诺.catch相结合似乎是错误的,也是错误的--我需要调用C(错误)的两个不同地方。

一个()抛出一个错误,而不是返回一个错误代码。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-23 13:59:34

您没有确切地说明A()是如何失败的。它可以抛出,也可以返回错误结果。我会给你们看一个方案。同步和异步混合的关键是始终返回承诺。这将为teh调用方提供一个一致的接口,无论该函数如何成功或失败。

如果您只担心A()抛出一个异常,并且它不返回错误代码,那么您可以这样做:

代码语言:javascript
复制
function someFunction() {
    try {
        var result = A();
        return B(result);
     } catch(err) {
         return Promise.reject(err);
     }
}

someFunction().then(function(result) {
    // code here to process the final result
}).catch(C);

如果您还有A()可以返回错误代码的情况,那么您可以这样做:

代码语言:javascript
复制
function someFunction() {
    try {
        var result = A();
        // check for error value
        if (result < 0) {
            throw result;
        }
        return B(result);
     } catch(err) {
         return Promise.resolve(err);
     }
}

请注意,这两种模式都避免在不需要的情况下创建额外的承诺。它们只在返回同步发生的错误时才创建额外的承诺。

对于这种特殊情况,蓝鸟承诺库有一个名为Promise.method的助手函数。Promise.method()的实用功能是它将函数自动包装在try/catch处理程序中,如果抛出任何同步异常,它会自动将它们转换为返回拒绝的承诺。你可以这样用它:

代码语言:javascript
复制
var someFunction = Promise.method(function() {
    var result = A();
    // check for error condition
    if (result < 0) {
        throw result;
    }
    return B(result);
});

someFunction().then(function(result) {
    // code here to process the final result
}).catch(C);
票数 2
EN

Stack Overflow用户

发布于 2016-06-23 13:23:29

我假设AB都可以在这里抛出错误。使用标准API,它可以如下所示:

代码语言:javascript
复制
function() {
  return new Promise((resolve, reject) => {
    try {
      resolve(A());
    } catch (error) {
      reject(error);
    }
  })
  .then(B)
  .catch(C);  
}

这将返回一个承诺,这个承诺要么用B的输出解决,要么返回C的输出,如果这提供了一个退路。如果这对您的用例有意义的话,您也可以考虑处理此函数之外的任何错误。

当使用蓝知更鸟时,这也是可能的:

代码语言:javascript
复制
function() {
  return Promise.method(A)().then(B).catch(C)
}
票数 2
EN

Stack Overflow用户

发布于 2016-06-23 14:23:14

我认为这样做的一个好方法是仍然使用同步函数的承诺。它使它在函数中保持一致,特别是当你想要对成功做出反应的时候,比如一个虚假的承诺。但关键是你要用一个立竿见影的承诺。看看这个关于ES6承诺的博客文章

代码语言:javascript
复制
// an immediately resolved promise
var a = Promise.resolve(A());

假设您已经创建了承诺并定义了C,如下所示:

代码语言:javascript
复制
var B = new Promise(function(resolve, reject) {  
   if (a) {
      resolve('success');  // fulfilled successfully
   }
   else {
      C('rejected');  // error, rejected
   }
})
.then((result) => {console.log('made it!');})
.catch((result) => {C('rejected');});

var C = (err)=>{console.log('error: ' + err); return err;}

这段代码应该做您想做的事情:

代码语言:javascript
复制
a.then((result) => B(result));

^这最后一行是最重要的,因为它使用A的输出调用B

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37992756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档