简体   繁体   English

在Promise解析器中捕获错误

[英]Catch an error inside of Promise resolver

I am not able to catch the Exception/Error that is happening inside of the Resolve promise. 我无法捕获Resolve promise中发生的异常/错误。 Can someone explain if there is a way to catch this error: 有人可以解释是否有办法捕获此错误:

createAsync = function() {
    var resolve, reject,
    promise = new Promise(function(res, rej) {
        resolve = res;
        reject = rej;
    });
    promise.resolve = resolve;
    promise.reject = reject;
    return promise;
};

promise = createAsync()
promise.then(function myresolver(){
    throw Error('wow')
})


// Catching the error here
try {
  promise.resolve()
} catch(err) {
  console.log( 'GOTCHA!!', err );
}

EDIT: 编辑:

Let me explain me better, I'm trying to create an API and the user only have access to the promise resolve/reject part: 让我更好地解释一下,我正在尝试创建一个API,用户只能访问promise resolve / reject部分:

// This is my API user does not have access to this part
promise = createAsync()
promise
.then(function(fun) {
    if (typeof fun != 'function')
        throw Error('You must resolve a function as argument')
}).catch(function(err){
    // Some internal api tasks...
    return Promise.reject(err)
})

Now the solution I would like to give him, but does not work: 现在解决方案我想给他,但不起作用:

// Here is where the user can resolve the promise.
// But must be able to catch the error
promise.catch(function(err){
    console.log("GOTCHA", err)
})
promise.resolve('This must be a function but is a string');

Any ideas? 有任何想法吗?


More info: Yes is an antipattern for the common usage. 更多信息:是的是常用的反模式。 This is a remote procedure call API, so the user must be able to reject or resolve. 这是一个远程过程调用API,因此用户必须能够拒绝或解决。 And the calls are async so the best approach is to use promises. 并且调用是异步的,因此最好的方法是使用promises。 I wouldn't say is an antipattern for this case. 我不会说这是一个反模式。 Actually is the only pattern. 实际上是唯一的模式。 (I can't use Async/Await) (我不能使用Async / Await)

Let me explain me better, I'm trying to create an API and the user only have access to the promise resolve/reject part. 让我更好地解释一下,我正在尝试创建一个API,用户只能访问promise resolve / reject部分。 Now the solution I would like to give him does not work. 现在我想给他的解决方案不起作用。 Any ideas? 有任何想法吗?

Don't put everything onto that initial promise object. 不要将所有内容都放在初始的promise对象上。 It sounds what you really need to expose to your user is a) a way to resolve (which includes rejection) and b) a way to get the result (promise) back. 听起来你真正需要向用户公开的是a)一种解决方法(包括拒绝)和b)一种获得结果(承诺)的方法。 So all you need to do is give him a function: 所以你需要做的就是给他一个功能:

function createAsync() {
    var resolve;
    var promise = new Promise(function(r) { resolve = r; })
    .then(function(fun) {
        if (typeof fun != 'function')
            throw Error('You must resolve a function as argument')
    }).catch(function(err){
       // Some internal api tasks...
       throw err;
    });
    return function(value) {
        resolve(value);
        return promise;
    };
}

and he'd use it like 他就像使用它一样

var start = createAsync();
// possibly later
start('This must be a function but is a string').catch(function(err){
    console.log("GOTCHA", err)
});
// or
start(Promise.reject(new Error('doomed to fail'))).catch(…);

but actually this pattern is still convoluted and much too complicated. 但实际上这种模式仍然令人费解,而且过于复杂。 Simply give your createAsync function a parameter (that might receive a promise if the user needs to delay passing the fun ) and be done with it: 只需给你的createAsync函数一个参数(如果用户需要延迟传递fun ,可能会收到一个声明)并完成它:

function createAsync(valu) {
    return Promise.resolve(val).then(function(fun) {
        if (typeof fun != 'function')
            throw Error('You must resolve a function as argument')
    }).catch(function(err){
       // Some internal api tasks...
       throw err;
    });
}

createAsync('This must be a function but is a string').catch(function(err) {
    console.log("GOTCHA", err)
});
// or
createAsync(new Promise(function(resolve) {
    // later
    resolve('This must be a function but is a string');
})).catch(function(err) {
    console.log("GOTCHA", err)
});

Warning: as pointed out by @torazaburo "Exporting" the resolve and reject functions provided to the executor (the function passed to the promise constructor), in your case by polluting the promise object with additional properties, is an anti-pattern. 警告:正如@torazaburo所指出的那样“导出”提供给执行程序的解析和拒绝函数(传递给promise构造函数的函数),在您的情况下通过使用其他属性污染promise对象,是一种反模式。 The entire point of the design of the promise constructor is that resolving and rejecting is isolated within the executor. promise构造函数的设计的全部要点是在执行程序中隔离解析和拒绝。 Your approach allows any random person who happens to acquire one of your promise objects to resolve or reject it, which is almost certainly not good program design. 您的方法允许任何碰巧获得您的一个承诺对象的随机人员解决或拒绝它,这几乎肯定不是好的程序设计。

With that warning in mind, your call to promise.resolve() doesn't reject the promise ... your promise.then ... throw will "reject" THAT promise (the one returned by .then) not the one in promise 记住这个警告,你对promise.resolve()调用不会拒绝承诺......你的promise.then ... throw将“拒绝”那个承诺(由.then返回的那个)而不是promise

rewrite your code as follows: 重写您的代码如下:

promise = createAsync()
promise // the call to promise.resolve will resolve THIS promise, so .then will execute
.then(function myresolver(){
    throw Error('wow')
}) // .then returns a NEW promise, in this case rejected with Error('wow')
.catch(function(e) {
    console.log("GOTCHA", e)
});

promise.resolve()

and you'll see the expected GOTCHA in the console 你会在控制台中看到预期的GOTCHA

Jaromanda's answer already explained that you must use a rejection handler or catch to handle asynchronous errors using promises. Jaromanda的回答已经解释过你必须使用拒绝处理程序或catch来使用promises来处理异步错误。

Also make sure to read torazaburo 's comment explaining why your approach is an anti-pattern. 另外请务必阅读torazaburo的评论,解释为什么你的方法是一种反模式。

If you really must use this approach and also require try/catch for some reason, ES7 gives you a way via async functions 如果你真的必须使用这种方法并且由于某种原因也需要try/catch ,那么ES7会为你提供一种通过异步函数的方法

 (async function f() { const createAsync = function() { var resolve, reject, promise = new Promise(function(res, rej) { resolve = res; reject = rej; }); promise.resolve = resolve; promise.reject = reject; return promise; }; const promise = createAsync(); promise.resolve(); // Catching the error here try { await promise.then(function() { throw Error('wow') }); } catch (err) { console.log('GOTCHA!!', err); } })() 

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

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