关于promise

我们知道js是异步执行的。那么什么是异步呢?
我理解的异步就是事件完成的顺序与和交付他们的时间顺序无关。举个例子来说:
你去一家餐厅吃饭,并且找到一个位置坐下,然后你想让服务员给你拿个菜单,但是这个时候服务员站在另一桌吃饭的人旁边等待服务,向你说对不起我不是异步的服务员,我只能服务完这桌人才能来为您服务。你的内心肯定很痛苦吧!!!
所以如果这个服务员是异步的,他应该就是给你拿来菜单。此时,你比那桌人后来,但是服务员仍然为你服务了。

传统的解决异步的方法或多或少都有缺点
以前我们采用回调或者是事件监听来解决异步,但是编程的时候你很容易发现,这不便于你维护,并且你没有办法在外部捕获这个错误,只能通过回调把这个error返回出去;还有一个问题是,假设我们有这样一种应用场景,你需要找出一堆文件中最大的那个文件,但是这个时候你并不知道它什么时候会比较完,所以你可能会设置一个count来计数,这个count应该是放在最顶层的,这个时候问题就出现了,一旦某个函数改变了这个count,我们就会得到错误的结果

这个时候我们有了promise

什么是promise呢,按照MDN官方的解释,promise对象是用于异步操作的,它表示一个尚未完成,并且可能在未来完成或者不完成的异步操作。
这似乎是有些难理解,我认为的promise是能够将异步操作队列化,使之按照我们期望的顺序执行,同时返回符合预期结果的一个对象。

为了理解它,我们先来看一个最为简单的promise

var test = new Promise(resolve=>{
			setTimeout(()=>{
				resolve('hello');
			},1000);
		}).then(value=>{
			console.log(value + 'world');  //hello,world
		})

在promise对象当中,包含着一个执行器,这个执行器需要执行一个异步操作,它耗时会比较长,当它执行完成之后,promise的状态就会变成fullfilled,一旦promise的状态变化了,就会触发then,then的参数value是promise参数中的函数执行后的结果。这其中的resolve是一个函数,它是执行成功时的函数回调。

通过查看promise的源码你会发现,为了让promise的执行器是一个异步函数,resolve当中使用了setTimeout函数

 var resolve = function (val) {
        if (self.status !== 'pending') {
            return;
        }
        setTimeout(function () {
            self.value = val;
            self.status = "resolved";
            resDeferreds.forEach(function (deferred) {
                deferred(self.value);
            });
        }, 0);
    };

看到了最为基本的情况,接下来我们来看一下如果then里面返回了一个promise会出现什么样的情况呢?

var p = new Promise(function(resolve) {
				console.log(1);
				console.log(resolve); //resolve是一个函数,它是一个执行成功时的回调函数
				setTimeout(function() {
					resolve(2);
				}, 1000);
			})
			.then(value => {
				console.log(value);   //2
				return new Promise(resolve => {
					setTimeout(() => {
						resolve('world');
					}, 2000);
				})
			})
			.then(value => {
				console.log(value + 'perfect!');  //world perfect
			});

执行这段代码,你会发现执行的结果是world perfect, 因为我们在第一个then的时候在promise中返回了一个resolve(‘world’),如果then之后是一个promise的话 它会等待这个promise执行完成,如果不是的话,它几乎是会立即执行下一个then

那么我们不在then中返回promise的情况

var promise1 = new Promise(resolve => {
				setTimeout(() => {
					resolve('hello');
				}, 1000)
			})
			.then(value => {
				console.log(value);   //hello
				console.log('world');
				(function() {  
					return new Promise(resolve => {  //这个返回值并不是在then的响应函数里面返回的
						setTimeout(() => {
							console.log('ywl');
							resolve('resolve');
						}, 3000)
					})
				})();
				return false;   //如果不返回的话,默认传递undefined
			})
			.then(value => {
				console.log(value + ' world'); //false world
			});

我们可以看到第二个then中打印出的是false world ,这是因为 第一个then当中的promise不是在then的响应函数里面返回的,而return false则是,我们自然而然的会想到,如果我不返回呢,这个时候就会默认返回一个undefined,那么最后打印出来的就过就成了 undefiend world

以上的情况都是立即.then,那么如果我对已经完成的promise,执行.then会出现什么样的现象呢?我们来看一下

console.log('promise start!');
		let promise = new Promise(resolve => {
			setTimeout(() => {
				resolve('hello,world');
			}, 1000)
		})

		setTimeout(() => {
			promise.then(value => {
				console.log(value);  //hello,world
			});
		}, 3000);

我们可以看到打印的结果是hello,world。这意味着我们可以执行同步函数那样,执行异步操作,当有多个回调时,promise的威力就显示出来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值