在浏览器的 javascripts webconsole 中,我读到了错误消息:
类型错误: promise 无法自行解决
我所做的是能够引发相同的错误消息 使用此代码:
var promise = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(promise);
},0);
});
但这只是证实了诸如解决之类的事情 本身的 promise 确实是可能发生的事情 这导致随后的 promise 被拒绝 由于发生错误;
console.log(promise);
// prints: Promise { <state>: "rejected" }
理想的答案将提供某种指导(步骤) 这有助于显示 javascript 源代码的哪一部分 实际上是导致错误的原因。
一个有用的答案也可以简单地列出所有方法(其他 比我提供的示例代码)可以导致 出现同样的错误。
已更新
源代码中唯一发生 new Promise(callback)
的地方看起来像这样,在我看来不能导致循环模式。
function xhrGet(url){
return new Promise((resolve,reject)=>{
var xhr = new XMLHttpRequest();
xhr.open("GET",url);
xhr.responseType = "arraybuffer";
xhr.addEventListener("load",function(){
resolve(xhr.response);
});
xhr.addEventListener("error",function(er){
reject(er);
});
xhr.send();
});
}
看来恕我直言,不太可能是罪魁祸首。
这里是 Firefox(版本 68)调试窗口的控制台输出的屏幕截图,遗憾的是它并不总是显示行号
最佳答案
当使用不同 Promise
调用 Promise 构造函数中的 resolve
时,构造的 Promise 解析的值将是该 Promise 的值传入 resolve
解析为。
const existingProm = new Promise(resolve => {
setTimeout(() => {
console.log('existing promise resolving');
resolve();
}, 2000);
});
var secondPromise = new Promise((resolve,reject)=>{
setTimeout(()=>{
console.log("second promise's resolve being called");
resolve(existingProm);
},1000);
});
secondPromise.then(() => {
console.log('second promise fulfilled');
});
正如您在上面的代码片段中看到的,尽管 secondPromise
的 resolve
在 1000 毫秒后调用,但 secondPromise
仅在 1000 毫秒后才真正解析。 2000 毫秒,因为 existingProm
(在 2000 毫秒后解析)已传递给 resolve
。
这就像从 .then
内部返回一个 Promise - 下一个 .then
将解析为返回的 Promise 的值决心。
但是,如果您将正在构造的 Promise 传递给用于构造 Promise 的同一个 resolve
,那么您就创建了一个循环 - resolve(promise);
意味着构造的 Promise 仅在 promise
解析后才会解析。但是promise
是构造了Promise。解释器看到这种循环情况并抛出错误(通过拒绝 Promise)。
任何类型的循环 Promise 循环都可能导致此错误。例如,如果 prom1
使用 prom2
调用其 resolve
,并且 prom2
调用其 resolve
> 与prom1
:
const prom1 = new Promise(resolve => {
setTimeout(() => {
console.log('prom1 resolve being called');
resolve(prom1);
}, 1000);
});
const prom2 = new Promise(resolve => {
setTimeout(() => {
console.log('prom2 resolve being called');
resolve(prom2);
}, 1000);
});
prom1.catch((e) => console.log(e.message));
要调试这样的错误,请查看生成错误的 Promise,并检查调用其 resolve
的内容,或者从 .then
返回的内容创造了 Promise。某处有一条环形链。例如:
const prom1 = new Promise(resolve => {
setTimeout(() => {
console.log('prom1 resolve being called');
resolve(prom1);
}, 1000);
});
const prom2 = new Promise(resolve => {
setTimeout(() => {
console.log('prom2 resolve being called');
resolve(prom2);
}, 1000);
});
prom1.catch((e) => console.dir(e.stack));
在我的机器上,这表明发生了错误
对应于这一行:
resolve(prom1);
这确实是 prom1
循环依赖的根源。
关于javascript - 如何调试 "TypeError: A promise cannot be resolved with itself",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57018864/