当前位置: 首页 > 知识库问答 >
问题:

promise构造函数与拒绝调用vs抛出错误

邵畅
2023-03-14

在以下代码中:

var p1 = new Promise(function (resolve, reject) {
    throw 'test1';
});

var p2 = new Promise(function (resolve, reject) {
    reject('test2');
});

p1.catch(function (err) {
    console.log(err); // test1
});

p2.catch(function (err) {
    console.log(err); // test2
});

在Promise api中使用拒绝(在p2中)和使用抛出错误(在p1中)之间有什么区别吗?

完全一样吗?

如果是相同的,那么为什么我们需要一个reject回调呢?


共有3个答案

申思远
2023-03-14

我知道这有点晚了,但我并不认为这两个答案完全回答了我发现这个问题时遇到的问题,这里有一个更完整的例子。

js prettyprint-override">var p1 = new Promise(function (resolve, reject) {
    throw 'test 1.1'; //This actually happens
    console.log('test 1.1.1'); //This never happens
    reject('test 1.2'); //This never happens because throwing an error already rejected the promise
    console.log('test 1.3'); //This never happens
});

var p2 = new Promise(function (resolve, reject) {
    reject('test 2.1'); //This actually happens
    console.log('test 2.1.1'); //This happens BEFORE the Promise is rejected because reject() is a callback
    throw 'test 2.2'; //This error is caught and ignored by the Promise
    console.log('test 2.3'); //This never happens
});

var p3 = new Promise(function (resolve, reject) {
    setTimeout(function() { reject('test 3.1');}, 1000); //This never happens because throwing an error already rejected the promise
    throw('test 3.2'); //This actually happens
    console.log('test 3.3'); //This never happens
});

var p4 = new Promise(function (resolve, reject) {
    throw('test 4.1'); //This actually happens
    setTimeout(function() { reject('test 4.2');}, 1000); //This never happens because throwing an error already rejected the promise
    console.log('test 4.3'); //This never happens
});

var p5 = new Promise(function (resolve, reject) {
    setTimeout(function() { throw('test 5.1');}, 1000); //This throws an Uncaught Error Exception
    reject('test 5.2'); //This actually happens
    console.log('test 5.3'); //This happens BEFORE the Promise is rejected because reject() is a callback
});

var p6 = new Promise(function (resolve, reject) {
    reject('test 6.1'); //This actually happens
    setTimeout(function() { throw('test 6.2');}, 1000); //This throws an Uncaught Error Exception
    console.log('test 6.3'); //This happens BEFORE the Promise is rejected because reject() is a callback
});


p1.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test1
});

p2.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test2
});

p3.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test3
});

p4.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test4
});

p5.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test5
});

p6.then(function (resolve) {
    console.log(resolve, "resolved")
}, function (reject) {
    console.log(reject, "rejected")
}).catch(function (err) {
    console.log(err, "caught"); // test6
});
子车煌
2023-03-14

不,没有,两者完全相同。唯一的区别以及我们需要reject的原因是当您需要异步拒绝时-例如,如果您正在转换基于回调的API,它可能需要发出异步错误信号。

var p = new Promise(function(resolve, reject){
    someCallbackApi(function(err, data){
        if(err) reject(err); // CAN'T THROW HERE, non promise context, async.
        else resolve(data);
    });
});
何楷
2023-03-14

在Promise api中使用拒绝(在p2中)和使用抛出错误(在p1中)之间有什么区别吗?

是的,您不能异步使用throw,而reject是回调。例如,某些超时:

new Promise(_, reject) {
    setTimeout(reject, 1000);
});

完全一样吗?

不,至少当其他代码跟随您的语句时不会throw立即完成解析器函数,同时调用reject在将promise“标记”为已拒绝后继续正常执行。

此外,如果抛出错误对象,引擎可能会提供不同的异常调试信息。

对于您的特定示例,您是正确的,p1p2从外部无法区分。

 类似资料:
  • 问题内容: 在下面的代码中: 从api 使用(in )和使用抛出错误(in )有什么区别? 完全一样吗? 如果相同,为什么我们需要回调呢? 问题答案: 从api 使用(in )和使用抛出错误(in )有什么区别? 是的,当是回调时,您不能异步使用。例如,一些超时: 完全一样吗? 不,至少在您的语句后面跟随其他代码时才不会。立即完成解析程序功能,同时调用继续正常执行-在“标记”了承诺被拒绝之后。 此

  • 问题内容: 我已经阅读了几篇有关该主题的文章,但是我仍然不清楚是否与抛出错误之间有区别。例如, 使用Promise.reject 使用抛出 我倾向于仅使用它,因为它更短,但我想知道一个相对于另一个是否有任何优势。 问题答案: 使用一个相对于另一个没有优势,但是,在特定情况下无法使用。但是,这些情况可以解决。 每当您进入promise回调时,都可以使用。但是,如果您在任何其他异步回调中,则必须使用。

  • 我有一个类(我不能修改),它只有一个构造函数,它接受一个参数,如下所示: 由于构造函数可以抛出错误,我想实现错误处理。我的第一次尝试是: 但是,现在在块的范围内,不能在其他地方使用。如果我理解正确,我不能在没有初始化的情况下声明对象,因此我可以在块之外声明。那么,我该如何捕捉构造函数抛出的错误呢? 编辑:为了澄清,这是在我的中,在中我将中止程序。此外,参数是一个将被打开的文件,因此没有已知的安全输

  • 问题内容: 是否有关于对象是否使用异常的构造函数清除的详细信息。 众所周知,定义此方法的时间很短。根据手册: Java编程语言不能保证哪个线程将为任何给定对象调用finalize方法。但是,可以保证,调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。如果finalize方法抛出未捕获的异常,则该异常将被忽略,并且该对象的终止将终止。 http://docs.oracl

  • 构造函数与析构函数是自动调用的。这些函数的调用顺序取决于执行过程进入和离开实例化对象范围的顺序。一般来说,析构函数的调用顺序与构造函数相反。但图6.9将介绍对象存储类可以改变析构函数的调用顺序。 全局范围中定义的对象的构造函数在文件中的任何其他函数(包括 main)执行之前调用(但不同文件之间全局对象构造函数的执行顺序是不确定的)。当main终止或调用exit函数时(见第18章)调用相应的析构函数

  • 当异常在构造函数中被抛出时,其中创建了多个对象,必须做些什么来清理内存。例如。 我的直觉是,将每个对new的调用放在一个单独的try-catch组中,并删除之前为其调用了,但这太冗长的所有对象(第一个try组不调用析构函数,第二个类调用第一个类的析构函数,第三个类调用前两个类的析构函数,以此类推)。我的问题是:最常见的处理方法是什么? 另外,假设类对象包含一个不是用new创建的对象(因为它在堆栈上