Promise对象(基础二)

Promise.prototype.then()

Promise实例具有then方式,即then方法时定义在原型对象Promise.prototype上的。它的作用是为Promise实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是Resolved状态得到回调函数,第二个参数(可选)是rejected状态的回调函数。
· then方法返回的是一个新的Promise实例(注意,不是原来那个promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

getJSON("/posts.json").then(function(json) {
	return json.post;
}).then.(function(post) {
 	//...
});
//上面的代码使用then方法依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数传入
//第二个回调函数。

采用链式的then可以指定一组按照次序调用的回调函数。这是,前一个回调函数有可能返回的还是一个Promise对象(即有异步操作),而后一个回调函数就会等待该Promise对象发生改变,再被调用。

getJSOn("/post/1.json").then(function(psot) {
	return getJSOn(psot.psot.commentURL);
}).then(function funcA(comments) {
	console.log("Resolved: ", comments);
}, function funcB(err) {
	console.log("Rejected: ", err);
});
//上面的代码中,第一个then方法指定的回调函数返回的是另一个Promise对象。这时,第二个then方法指定的
//回调函数就会等待这个新的Promise对象状态发生变化。如果变为Resolved,就调用funcA; 如果状态变为
//Rejected,就调用funcB。

如果采用箭头函数,上面的代码可以写的更简洁

getJSON("/post/1.json").then(
	post => getJSON(post.commentURL)
).then(
	comments => console.log("Resolved: ", comments),
    err => console.log("rejected: ", err)
);

Promise.prototype.catch()

Promise.prototype.catch方法.then(null,rejection)的别名,用于指定发生错误时回调函数。

getJSON('/posts.json').then(function(psots){
	//...
}).catch(function(error) {
	//处理getJSON 和前一个回调函数运行时发生错误
	console.log('发生错误!', error)
});
//上面的代码中,getJSON 方法返回一个Promise 对象,如果该对象状态变为Resolved, 则会回调 then
//方法指定的回调函数; 如果异步操作抛出错误,状态就会变为Rejected,然后调用 catch 方法指定的回调
//函数处理这个错误。另外,then方法指定的回到函数如果再运行中抛出错误,也会被catch方法捕获。
p.then((val) => console.log('culfilled:', val))
	.catch((err) =>console.log('rejected:', err));
	
	//等同于
	p.then((val) => console.log('fulfilled:', val))
		.then(null, (err) => console.log("rejected:", err));
	//下面是一个例子
	var  promise = new Promise (function(resolve, reject){
		throw new Error('test');
	});
	promise.catch(function(error) {
		console.log(error);
	});
	//Error:test
	//上面代码中,Promise抛出一个错误就被cathch 方法指定的回调函数所捕获。注意,上面的写法
	//余下卖弄两种写法时等价	
//写法一
	var promise = new Promise(function(resolve, reject) {
		try {
		 	throw new Error('test');
		 } cathch (e)' {
		 	reject(e);
		 }
	});
	promise.catch(function(error) {
		console.log(error):
	});

//写法二
var	 promise = new Promise(function(resolve, reject) {
	reject(new Error('test'));
});
promise.catch(function(error) {
	console.log(error);
});


//比较上面的两种写法,可以法相reject方法的作用等同于抛出错误。

如果Promise状态已经变成Resolced,在抛出错误是无效的。

var promise = new Promise (function(resolve, reject) {
	resolve('ok');
	throw new Error('test');
});
promise
	.then(function(value) { console.log(value) })
	.catch(function(error) { console.log(error) });
	//ok
//上面的代码中,Promise在 resolve 语句后面再抛出错误,并不会捕获,等于没有抛出。
//因为Promise的状态一旦改变,就会永久保持该状态,不会再改变了。

Promise 对象的错误具有 “冒泡” 性质,会一直向后传递,知道被捕获为止。也就是说,错误总是会被下一个catch语句捕获。

getJSON('/post/1.json').then(function(post) {
		return getJSON(post.commentURL);
	}).then.(function(comments) {
		//some code
	}).catch(function(error) {
	//处理前面3个Promise产生的错误
	})
//上面的代码中,一共有3个Promise对象:一个有getJSON产生,两个有then产生。其中任何一个
//抛出的错误都会被最后一个catch捕获。		

一般来说,不要再then方法中定义Rejected状态的回调函数(即then的第二个参数),而应总是使用catch方法。

//bad
promise
	.then(function(data) {
		//success
	},function(err) {
		//error
	};

//good
promise
	.then(function(data) {
		//success
	})
	.catch(function(err) {
		//error
	});
//上面的代码中,第二种写法要好于第一种写法,理由事第二种写法可以捕获前面then方法
//执行中的错误,也更接近同步的写法(try/catch)。因此,建议使用catch方法,而不
//使用then方法的第二个参数。

跟传统的try/catch代码块不同的是,如果没有使用catch方法指定错误处理的回调函数,Promise对象抛出的错误不会传递到外层代码,既不会有任何反应。

var somAsyncThing = function(){
	return new Promise (function(resolve, reject) {
		resolce(x + 2);
		});
	};
	somAsyncThing().then(function() {
		console.log('everything is great');
	});
//上面的代码中,someAsyncThing 函数产生的 Promise 对象会报错,但是由于没有指定
//catch方法,因而这个错误不会被捕获,也不会传递到外层代码。正常情况下,运行后不会有
//任何输出,但是浏览器此时会打印出错误 “PeferenceError:x is not defined”,不
//过不会终止脚本执行,如果这个脚本放在服务器中执行,退出码就是 0 (即表示执行成功)。
var promise = new Promise(function (resolce, reject) {
	resolve('ok');
	setTimeout(function () { throw new Error('test') }, 0)
})
promise.then(function (value) { console.log(value) });
// ok
// Uncaught Error: test
//上面的代码中,Promise 指定在下一轮“事件循环“再抛出错误。到了那个时候,Promise
//的运行已经结束,所以这个错误是在Promise 函数体外抛出的,会冒泡到最外层,成了未捕获的错误。 

Node 有一个 unhandledRejection 事件,专门监听未捕获的reject的错误。

process.on('unhandledRejection', function (err, p) {
	console.error(err.stack)
});
//上面的代码中,unhandledRejected 事件的监听函数有两个参数,第一个事错误对象,第二个事报错的
//Promise 实例,可以用于了解发生错误的环境信息。

需要注意的是,catch 方法放回的化石一个 Promise 对象,因此后面还是可以接着调用 then方法。

var someAsyncThing = function() {
	return new Promise(function(resolve, reject) {
		resolve(x + 2);
	});
};

someAsyncThing()
.catch(function(error) {
	console.log('oh no', error);
)
.then(function() {
	console.log('carry on');
})
// oh no [ReferenceError: x is not defined]
// carry on
//上面的代码运行完 catch 方法指定的回调函数后会接着运行后面那个 then 方法指定的回调函数

如果没有报错,则会跳过 catch 方法。

Promise.resolve()
.catch(function(error) {
	console.log('oh no',error);
})
.then(function() {
	console.log('carry on');
})
// carry on
//上面的代码因为没有报错而跳过 catch 方法,直接执行了后面的then 方法。此时要是
//then 方法里面报错,就与前面的catch 无关了。

catch 方法中还能再抛出错误。

var	someAsyncThing = function() {
	return new Promise(function(resolve, reject) {
		//下面一行会报错,因为x没有声明
		resolve(x +2);
	})
};

someAsyncThing().then(function() {
	return sonmeOtherAsyncThing();
}).catch(function(error) {
	console.log('oh no', error);
	//下面一行会报错,因为y没有声明
	y + 2;
}).then(function() {
	console.log('carry on');
});
//oh no [ReferenceError: x is not defined]
//上面的代码中catch 方法抛出一个错误,因为后面没有别的 catch 方法,导致这个错误不会被捕获,
//也不会传递到外层。

如果改写一下。结果就不一样。

someAsyncThing().then(function() {
	return someOtherAsyncThing();
}).catch(function(error) {
	console.log('oh no',error);
	//下面一行会报错,因为y没有声明
	y + 2;
}).catch(function(error) {
	console.log('carry on',error);
});
//oh no [RefeerenceError: x is not defined]
//carry on [ReferenceError: y is not feined]
//上面的代码中,第二个 catch 方法用来捕获前一个 catch 方法抛出的错误。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值