我如何拒绝一个承诺,返回的异步/等待函数?

例如最初:

foo(id: string): Promise<A> {
  return new Promise((resolve, reject) => {
    someAsyncPromise().then((value)=>resolve(200)).catch((err)=>reject(400))
  });
}

翻译成async/await:

async foo(id: string): Promise<A> {
  try{
    await someAsyncPromise();
    return 200;
  } catch(error) {//here goes if someAsyncPromise() rejected}
    return 400; //this will result in a resolved promise.
  });
}

那么,在这种情况下,我如何正确地拒绝这个承诺呢?


当前回答

这不是对@ tj的回答。克劳德。只是回复注释“实际上,如果异常将被转换为拒绝,我不确定如果它是一个错误,我是否真的会被打扰。我只抛出错误的理由可能并不适用。”

如果你的代码使用async/await,那么用一个Error而不是400来拒绝仍然是一个很好的做法:

try {
  await foo('a');
}
catch (e) {
  // you would still want `e` to be an `Error` instead of `400`
}

其他回答

编写async函数的一个更好的方法是从一开始就返回一个挂起的Promise,然后在Promise的回调中处理拒绝和解决,而不是在错误时抛出一个被拒绝的Promise。例子:

async foo(id: string): Promise<A> {
    return new Promise(function(resolve, reject) {
        // execute some code here
        if (success) { // let's say this is a boolean value from line above
            return resolve(success);
        } else {
            return reject(error); // this can be anything, preferably an Error object to catch the stacktrace from this function
        }
    });
}

然后你只需在返回的promise上链接方法:

async function bar () {
    try {
        var result = await foo("someID")
        // use the result here
    } catch (error) {
        // handle error here
    }
}

bar()

来源-本教程:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

我有一个建议,以一种新颖的方法正确处理拒绝,而不需要多个try-catch块。

import to from './to';

async foo(id: string): Promise<A> {
    let err, result;
    [err, result] = await to(someAsyncPromise()); // notice the to() here
    if (err) {
        return 400;
    }
    return 200;
}

哪里去。Ts函数应该从:

export default function to(promise: Promise<any>): Promise<any> {
    return promise.then(data => {
        return [null, data];
    }).catch(err => [err]);
}

感谢迪马·格罗斯曼在以下链接。

您可以创建一个包装器函数,它接受一个promise,如果没有错误则返回一个包含数据的数组,如果有错误则返回错误。

function safePromise(promise) {
  return promise.then(data => [ data ]).catch(error => [ null, error ]);
}

在ES7和异步函数中像这样使用它:

async function checkItem() {
  const [ item, error ] = await safePromise(getItem(id));
  if (error) { return null; } // handle error and return
  return item; // no error so safe to use item
}

可能还应该提到的是,您可以在调用异步操作之后简单地链接catch()函数,因为在底层仍然返回一个承诺。

await foo().catch(error => console.log(error));

这样,如果您不喜欢try/catch语法,就可以避免使用它。

这不是对@ tj的回答。克劳德。只是回复注释“实际上,如果异常将被转换为拒绝,我不确定如果它是一个错误,我是否真的会被打扰。我只抛出错误的理由可能并不适用。”

如果你的代码使用async/await,那么用一个Error而不是400来拒绝仍然是一个很好的做法:

try {
  await foo('a');
}
catch (e) {
  // you would still want `e` to be an `Error` instead of `400`
}