简体   繁体   English

尝试兑现承诺

[英]Try and catch around promise

I need to write a function that returns a promise, where first I call a synchronous function A() which returns some result. 我需要编写一个返回promise的函数,首先我要调用一个返回一些结果的同步函数A()。 Then return a function B(result) where B is a promise which takes in the result of A(). 然后返回一个函数B(result),其中B是一个承诺,它接受A()的结果。 If either function fails I want the same error function C(error) to get called where C is a promise. 如果任何一个函数失败,我都希望在C是一个诺言的情况下调用相同的错误函数C(error)。 What is the best way of writing this. 编写此内容的最佳方法是什么。 This is what I have but think there is obvious way I am missing 这就是我所拥有的,但我认为有一种明显的失踪方式

function() {
    try {
        var result = A();
        return B(result)
            .catch(function(error) {
                return C(error);
            });
     }
     catch(error) {
         return C(error);
     }
}

It seems wrong combining synchronous try and catch with a promise .catch and also wrong there are two different places I need to call C(error). 将同步try and catch与promise .catch结合起来似乎是错误的,而且我在两个不同的地方需要调用C(error)。

A() throws an error rather than returning an error code. A()引发错误而不是返回错误代码。

I'm assuming that both A and B can throw errors here. 我假设AB都可以在这里抛出错误。 Using the standard API it could look like this: 使用标准API可能看起来像这样:

function() {
  return new Promise((resolve, reject) => {
    try {
      resolve(A());
    } catch (error) {
      reject(error);
    }
  })
  .then(B)
  .catch(C);  
}

This will return a promise that's either resolved with the output of B or the output of C , if that provides a fallback. 如果提供回退,则将返回可以由B的输出或C的输出解析的promise。 You can also consider handling any errors outside of this function if that makes sense for your use case. 如果对您的用例有意义,您还可以考虑处理此函数以外的任何错误。

When using Bluebird this should also be possible: 使用Bluebird时,这也应该可行:

function() {
  return Promise.method(A)().then(B).catch(C)
}

You don't say exactly how A() fails. 您没有确切说明A()如何失败。 It could either throw or it could return an error result. 它可能会抛出,也可能返回错误结果。 I'll show a scheme for both. 我将为两者展示一个方案。 The key to a mix of sync and async is to always return a promise. 同步和异步混合的关键是始终返回承诺。 This will give you a consistent interface for teh caller no matter how the function succeeds or fails. 无论函数成功与否,这都将为您提供一个一致的接口给调用者。

If you are only worried about A() throwing an exception and it doesn't return an error code, then you can do this: 如果仅担心A()引发异常并且它不返回错误代码,则可以执行以下操作:

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);

If you also have the case where A() can return an error code, then you can do this: 如果还存在A()可以返回错误代码的情况,则可以执行以下操作:

function someFunction() {
    try {
        var result = A();
        // check for error value
        if (result < 0) {
            throw result;
        }
        return B(result);
     } catch(err) {
         return Promise.resolve(err);
     }
}

Note that both of these patterns avoid creating an extra promise if it isn't needed. 请注意,这两种模式都避免了在不需要时产生额外的承诺。 They only create the extra promise when returning an error that occurred synchronously. 它们仅在返回同步发生的错误时才创建额外的promise。


The Bluebird promise library has a helper function for this particular circumstance called Promise.method . 在这种特殊情况下, Promise.method 具有一个名为Promise.method的辅助函数。 The utility of Promise.method() is that it automatically wraps your function in a try/catch handler and if there are any synchronous exceptions thrown, it automatically turns them into returning a rejected promise. Promise.method()的实用程序是自动将您的函数包装在try / catch处理程序中,并且如果引发任何同步异常,它将自动将它们转换为返回被拒绝的诺言。 You could use it like this: 您可以这样使用它:

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);

I think a good way to do this would be to still use promises for the synchronous function. 我认为,执行此操作的一种好方法是仍将诺言用于同步功能。 It keeps it consistent within a function, especially if you want something to respond to the success like a pseudo-promise. 它使函数内的内容保持一致,特别是如果您希望某些东西对成功做出回应,例如伪承诺。 But the key is that you'd use an immediately resolved promise. 但是关键是您将使用立即解决的承诺。 Take a look at this blog post on ES6 Promises . 看一下有关ES6 Promises的博客文章

// an immediately resolved promise
var a = Promise.resolve(A());

assuming you've already created the promise and defined C like so: 假设您已经创建了promise并定义了C,如下所示:

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;}

this code should do what you want: 此代码应执行您想要的操作:

a.then((result) => B(result));

^ this last line is the most important, since it uses the output for A to call B ^这最后一行是最重要的,因为它使用A的输出来调用B

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM