我正在设法把注意力集中在JavaScript中的诺言上。我当时的幻想是,一旦解决了诺言,就再也回不去了。为了测试我写了一个小脚本。我看到返回的第一条消息是解决消息“ 1 resolve 2”等。我希望第一条消息是“ 0 reject 1”。
for (let i = 0; i < 10; i++) {
let p = new Promise((resolve, reject) => {
let a = 1 + (i % 2)
if (a === 2) {
resolve(i + ' resolve ' + a)
} else {
reject(i + ' reject ' + a)
}
})
p.then((message) => {
console.log(message)
}).catch((message) => {
console.log(message)
})
}
在控制台上:
[Log] 1 resolve 2
[Log] 3 resolve 2
[Log] 5 resolve 2
[Log] 7 resolve 2
[Log] 9 resolve 2
[Log] 0 reject 1
[Log] 2 reject 1
[Log] 4 reject 1
[Log] 6 reject 1
[Log] 8 reject 1
< Promise {status: "pending"}
感谢您的帮助。...
阅读后
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then
我明白了这段代码。捕获被删除。
for (let i = 0; i < 10; i++) {
let p = new Promise((resolve, reject) => {
let a = 1 + (i % 2)
if (a === 2) {
resolve(i + ' resolve ' + a)
} else {
reject(i + ' reject ' + a)
}
})
p.then((message) => {
console.log(message)
}, failed => {
console.log(failed)
})
}
在控制台上:
[Log] 0 reject 1
[Log] 1 resolve 2
[Log] 2 reject 1
[Log] 3 resolve 2
[Log] 4 reject 1
[Log] 5 resolve 2
[Log] 6 reject 1
[Log] 7 resolve 2
[Log] 8 reject 1
[Log] 9 resolve 2
< Promise {status: "pending"}
答案 0 :(得分:4)
通过使用浏览器开发工具的控制台,并可能设置断点,您可以了解幕后情况(如果您使用Chrome或{{3},则本文可能会有所帮助}):
如您所见,您的所有10个诺言都在执行(解析/拒绝)之前创建。
有趣的是,在您的代码中,首先处理了已解决的承诺。
如果在两个单独的定义中定义处理程序,则会获得预期的结果:
p.then((message) => {
console.log(message)
})
p.catch((message) => {
console.log(message)
})
输出:
答案 1 :(得分:2)
重点是,Promise被用作异步调用,因此,当您执行循环并为每次迭代创建一个新的Promise时,您将创建一个新的实例,并且每个实例都可以单独执行时间。
但这甚至意味着什么?原因是,当您在一个循环中创建10个新Promises时,每个Promise都会在自己的时间内执行,并且很可能会弄乱您的Promise解决顺序。
您可以怎么解决?您可以使用await
命令来等待每个诺言的解决,例如下面的代码:
for (let i = 0; i < 10; i++) {
let p = new Promise((resolve, reject) => {
let a = 1 + (i % 2)
if (a === 2) {
resolve(i + ' resolve ' + a)
} else {
reject(i + ' reject ' + a)
}
})
await p.then((message) => {
console.log(message)
}).catch((message) => {
console.log(message)
})
}
答案 2 :(得分:0)
因为JavaScript是单线程:
以前列出的方法不是javascript enterpreter(例如V8 Engine)的一部分,它委托给事件循环,后者是浏览器或nodejs的一部分。 more information here
基本上,此代码委派给第三方(节点,浏览器),由第三方决定何时{该顺序}和按哪个顺序执行此microtasks集合并返回主线程。
是为什么遵循以下代码:
let p = new Promise((resolve, reject) => {
resolve('micro task thread');
});
p.then((message) => {
console.log(message)
}).catch((message) => {
console.log(message)
});
console.log('main thread');
将先显示“主线程”,然后显示“微任务线程”,但是您没有明显的延迟代码。这是因为所有主线程函数调用将在对eventLoop执行任务之前执行。
在大多数情况下,事件循环将在第一次出现时执行收集。
答案 3 :(得分:0)
我确实在这里找到了解决方案: MDN promise then
for (let i = 0; i < 10; i++) {
let p = new Promise((resolve, reject) => {
let a = 1 + (i % 2)
if (a === 2) {
resolve(i + ' resolve ' + a)
} else {
reject(i + ' reject ' + a)
}
})
p.then((message) => {
console.log(message)
}, failed => {
console.log(failed)
})
}
promise.catch()正在调用promise.then(未定义,onreject)。这就是为什么始终要首先解决问题的原因。