Discuss / JavaScript / catch和then互换位置

catch和then互换位置

Topic source

//在这个例子里我把catcht和then调换了位置, 执行之后发现有问题 new Promise(function (resolve, reject) { log('start new Promise...'); var timeOut = Math.random() 2; log('set timeout to: ' + timeOut + ' seconds.'); setTimeout(function () { if (timeOut < 1) { log('call resolve()...'); resolve('200 OK'); } else { log('call reject()...'); reject('timeout in ' + timeOut + ' seconds.'); } }, timeOut 1000); }).catch(function (r) { log('Done: ' + r); }).then(function (reason) { log('Failed: ' + reason); });

这是输出小于1的情况, 没问题: start new Promise...

set timeout to: 0.6963593041800307 seconds.

call resolve()...

Failed: 200 OK

这是输出大于1的情况, 多输出一个Failed: undefined: start new Promise...

set timeout to: 1.4453681319996927 seconds.

call reject()...

Done: timeout in 1.4453681319996927 seconds.

Failed: undefined

是then(function(){}).catch(function(){})换位置肯定错啊

z-7ing

#3 Created at ... [Delete] [Delete and Lock User]

Promise 不论成功或失败都会调用 then 然而catch() 只有当 promise 失败时才会调用

所以当失败的时候既执行了then又执行了catch,只不过reject只会将参数传递给catch方法,并不传递then方法所以顺序写反失败后then就输出了undefined,而catch是正常输出结果

吸猫二哈

#4 Created at ... [Delete] [Delete and Lock User]

虽然知道原因,但我觉得我讲起来你们可能听不懂,因为要阅读文档,了解了这些方法的参数和返回值才会懂。我大概说一下吧: 输出大于1 的时候,执行 catch 的回调函数时输出了 Done: timeout in 1.4453681319996927 seconds. 然后因为 catch 的回调函数没有返回值,所以 catch 方法返回的 promise 对象的状态变为了 'resolved',value 值变为了 undefined。由于 catch 方法返回的 promise 对象状态变为 'resolved',所以触发了then 方法的回调函数,输出了 'Failed: ' + value, 即:Failed: undefined ...... 是不是看得很糊涂,不明白的同学还是多看看官方文档吧

Promise 无论成功或者失败都会进入then,在then中接受错误的对象后再进入的catch,所以换位子回出错。

小__马__哥

#6 Created at ... [Delete] [Delete and Lock User]

我理解的不知道对不对:Promise构造对象之前执行传入的方法,会携带成功或失败后的信息,并将携带的信息传递给接下来执行的then方法或者catch方法。而Promise执行完then方法或catch方法之后返回的Promise对象不再携带处理成功或失败的结果了,所以你再次调用then方法,信息是undefined。你看接下来的示例,如果想连续使用then方法,你要重新构造Promise对象传入相应处理函数然后才能返回处理结果

特意登录 恢复 吸猫二哈 同学

你的说法

虽然知道原因,但我觉得我讲起来你们可能听不懂,因为要阅读文档,了解了这些方法的参数和返回值才会懂。我大概说一下吧: 输出大于1 的时候,执行 catch 的回调函数时输出了 Done: timeout in 1.4453681319996927 seconds. 然后因为 catch 的回调函数没有返回值,所以 catch 方法返回的 promise 对象的状态变为了 'resolved',value 值变为了 undefined。由于 catch 方法返回的 promise 对象状态变为 'resolved',所以触发了then 方法的回调函数,输出了 'Failed: ' + value, 即:Failed: undefined ...... 是不是看得很糊涂,不明白的同学还是多看看官方文档吧

不对

测试
		<script>
			function test(resove, reject) {
				const random = Math.random() * 2
				setTimeout(function() {
					if (random < 1) {
						console.log('call resolve')
						resove('200 ok')
					} else {
						console.log('call reject')
						reject('timeout ' + random + ' seconds')
					}
				}, random * 1000)
				// if (random < 1) resove('小于一')
				// else reject('不小于1')
			}
			const promise = new Promise(test)
			promise.catch(response => {
				console.log(promise);
				console.log(response);
			}).then(error => {
				console.log(promise);
				console.log(error);
			})
		</script>

结果

call reject
test.html:26 Promise {<rejected>: "timeout 1.9567438656987801 seconds"}
test.html:27 timeout 1.9567438656987801 seconds
test.html:29 Promise {<rejected>: "timeout 1.9567438656987801 seconds"}
test.html:30 undefined

也是需要多看看官方文档啊

devil3lood

#8 Created at ... [Delete] [Delete and Lock User]

回复以下 庸人自扰Ray 同学

您的代码有问题,在catch与then中调用的是同一个promise对象,而吸猫二哈所讲的catch方法返回的promise对象并不是这个对象。

正确代码应该是

function test(resove, reject) {
    const random = Math.random() * 2
    setTimeout(function() {
        if (random < 1) {
            console.log('call resolve')
            resove('200 ok')
        } else {
            console.log('call reject')
            reject('timeout ' + random + ' seconds')
        }
    }, random * 1000)
    // if (random < 1) resove('小于一')
    // else reject('不小于1')
}
const promise = new Promise(test)
p1 = promise.catch(response => {
    console.log(promise);
    console.log(response);
})
p2 = p1.then(error => {
    console.log(p1);
    console.log(error);
})

而代码运行的结果为

call reject
VM2060:17 Promise {<rejected>: "timeout 1.8380489456267801 seconds"}
VM2060:18 timeout 1.8380489456267801 seconds
VM2060:21 Promise {<fulfilled>: undefined}
VM2060:22 undefined

您也需要多多看看官方文档啊

(上述的fulfilled即为吸猫二哈说的resolved,详情请查看https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise

再次阅读了MDN文档,然后测试了你的代码,我想说的是,const promise = new Promise(test),这个const promise返回的只有一个状态,也就是说,只能走resove和reject之一,而catch、then代表他们的状态。我的代码想说明的是promise只能存在一个状态,另一个是不存在的,当然是undefined

回复

devil3lood

catch方法返回的promise对象并不是这个对象

这个说法也不对吧,

p1 = promise.catch(response => {
    console.log(promise);
    console.log(response);
})

没有返回 promise啊,这里只是一个箭头函数,并没有返回任何东西.........


  • 1
  • 2

Reply