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

lan*_*nte 55 javascript promise

在以下代码中:

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
});
Run Code Online (Sandbox Code Playgroud)

从api 使用reject(in p2)Promise和使用错误(in p1)之间有什么区别throw吗?

它完全一样吗?

如果它相同,为什么我们需要reject回调呢?

Ber*_*rgi 60

从api 使用reject(in p2)Promise和使用错误(in p1)之间有什么区别throw吗?

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

new Promise(_, reject) {
    setTimeout(reject, 1000);
});
Run Code Online (Sandbox Code Playgroud)

它完全一样吗?

不,至少在其他代码遵循您的陈述时不会.throw立即完成解析器功能,同时reject正常调用继续执行 - 在将"承诺"标记为拒绝之后.

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

对于您的具体示例,您是正确的,p1并且p2与外部无法区分.

  • "如果抛出错误对象,引擎可能会提供不同的异常调试信息." - 我认为这部分不适用于抛弃vs拒绝,或者你的意思是一般吗? (2认同)
  • 如果你发现一个肯定会提交错误报告 - 错误在创建时创建堆栈跟踪而不是在抛出时创建堆栈跟踪:) (2认同)

Ben*_*aum 31

不,没有,两者完全相同.我们需要的唯一区别和原因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);
    });
});
Run Code Online (Sandbox Code Playgroud)

  • @PeterWhitfield我可以告诉它仍然可以 - 它们在OP的用例中完全相同_但是在另一个使用模式中给出了另一个输入_它们不同. (8认同)
  • 可能是因为你说'完全相同'然后继续解释差异......? (3认同)

Jon*_*Rys 29

我知道这有点晚了,但我并不认为这些答案中的任何一个都完全回答了我在发现这个问题时所遇到的问题,这里有一个更全面的例子.

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
});
Run Code Online (Sandbox Code Playgroud)