es 异步流程之Promise篇

本文深入讲解Promise的基础概念和使用技巧,包括resolve/reject、then/catch、链式调用、all和race方法,帮助读者理解如何利用Promise改善异步编程中的回调地狱问题。
部署运行你感兴趣的模型镜像

一、前言

由于js是单线程的,所以异步操作就显得非常重要。而promise能便于我们异步编程。这里只记录promise的主要功能。

二、理由

为什么会出现Promise这种东西呢?

在Promise出现前,一般使用回调函数。而在出现大量串行执行的异步操作时便会出现 “ 回调地狱”

func1((val1)=>{
    func2((va2)=>{
        func3((val3)=>{
             func4((val4)=>{
                ...
             })
        })
    })
})

这种代码不仅样子不好看、不直观,而且增加了debug难度。

所以需要一种新的异步编程方法,promise应运而生。

三、使用

1.resolve / reject

首先看一个Promise实例:

var p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p1");
	},1000)
    //使用setTimeout模仿异步操作
})

使用Promise的要点之一就是 new 一个Promise对象,传入一个形如 (resolve,reject){ } 的函数。

这里resolve的意思是把得到的正确结果处理掉,而reject则是抛出错误结果或者错误。简单地说,你只需要在异步操作后resolve正确结果,或者reject错误就行辽。

但是请注意!只能 resolve 或者 reject 一次,多余的会无视。

var p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p1");
		resolve("p11");
		reject("p1111");
	})
})

p1.then((val)=>{
	console.log(val); // 结果为: p1
})

2.then / catch

看完上一条,你可能会有疑问:“ resolve后怎么自己处理这个值? ”

Promise有一点很巧妙的是,它把异步的执行部分和处理部分分开了。上面传入的 (resolve,reject){ } 是为执行部分,下面介绍的 then / catch 为 处理部分。

var p1 = new Promise((resolve,reject)=>{    //执行部分
	setTimeout(()=>{
		resolve("p1"); //弹出 p1
	})
})
       //这里收到 p1
p1.then((value)=>{    //处理部分
    console.log(value); // p1
})

你可以假设 resolve / reject 弹出了异步结果,然后 then 会接住这个结果然后执行处理部分的代码。

如果需要截获 reject 的错误则用 catch

var p1 = new Promise((resolve,reject)=>{    //执行部分
	setTimeout(()=>{
		reject("p1 error"); //弹出 "p1 error"
	})
})
       
p1.then((value)=>{    //处理部分
    console.log(value); //这里收不到reject的结果
}).catch((error)=>{
    console.log(error); //catch可以收到reject的结果
})

3.promise链式调用

前面的内容你可能觉得并没有解决 “回调地狱” 的问题,而 promise链式调用 其实才是关键。

举个简单栗子:

var p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p1");
	})
})

p1.then((value)=>{
    console.log(value);
	return "p2";
}).then((value)=>{
	console.log(value);
	return "p3";
}).then((value)=>{
	console.log(value);
})
/*结果:
   p1
   p2
   p3
*/

 可以发现,上一个 then 中 return 的结果会在下一个then中获得。这里只是return了字符串,假设return 的是Promise对象呢?

再举个栗子:

var p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p1");
	})
})

p1.then((value)=>{
	console.log(value);
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{resolve("p2")},1000);
	});
}).then((value)=>{
	console.log(value);
	return new Promise((resolve,reject)=>{
		setTimeout(()=>{resolve("p3")},1000);
	});
}).then((value)=>{
	console.log(value);
})
/*结果:
   p1
   p2
   p3
*/

只要return  Promise , 下一个 then 便会获得resolve的结果。这样大大改善了 “回调地狱” 。

4.all

Promise 提供了 all方法,用于同时运行多个 Promise对象,然后全部运行完后才返回全部结果。

var p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p1");
	})
})
var p2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p2");
	})
})
p1.then((value)=>{
	return value;
})
p2.then((value)=>{
	return value;
})
//同时运行 p1和p2
Promise.all([p1,p2]).then((val)=>{ 
	console.log(val); // [ 'p1', 'p2' ]
});

5.race

Promise 还提供了 race 方法,用于同时运行多个 Promise对象,然后返回最先运行完的结果(但另外一个还是会继续运行,只是不返回结果了)

var p1 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p1");
	},2000)
})
var p2 = new Promise((resolve,reject)=>{
	setTimeout(()=>{
		resolve("p2");
	},1000)
})
p1.then((value)=>{
	return value;
})
p2.then((value)=>{
	return value;
})
//同时运行
Promise.race([p1,p2]).then((val)=>{
	console.log(val); // 'p2'
});

 

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值