Promise函数
很多时候,作为一个前端程序猿,不可避免的会用到promise函数,但是在快餐式的文化氛围中,我们常常会丢掉深入思考的机会。可能对于promise函数,都已经司空见惯了,在这里提出两个问题,一是为什么要用?二是如何使用?
我们摒弃官方文档那些高大上且晦涩难懂的解释,这里给出一个简单的例子。假如现在后台有两个请求,B请求需要根据A请求获取的数据来发送请求,就是B需要依赖A。举个栗子,在一个音乐App中,程序猿需要先发送A请求获取排行,歌单,歌手等分类列表,之后再将例如歌单作为请求参数向后台发送B请求,以获取歌单的详情页。这?这个简单,学过异步编程的我们不是分分钟的事?几乎应激性的不假思索的写下来如下程序。
var songs = []
var songList = []
//A请求
ajax.get({
methods: 'GET',
url: '/songList'
}).then((res) => {
songList = res.data
})
//B请求
ajax.get({
methods: 'GET',
url: '/songs',
query: {song: songList[0] }
}).then((res) => {
songs = res.data
})
问题解决了?上面的代码,其实有一个致命性的问题。代码排列的先后顺序并不能决定请求的完成的顺序,因此B请求有可能是失败的,这是非常多刚入门的小白忽略的问题。ok,下面我们稍微修改一下代码。
var songs = []
var songList = []
var flag = false //标识位
//A请求
ajax.get({
methods: 'GET',
url: '/songList'
}).then((res) => {
songList = res.data
flag = true
})
//循环检测
let timer = setInterval(() => {
if (flag){
//B请求
ajax.get({
methods: 'GET',
url: '/songs',
query: {song: songList[0] }
}).then((res) => {
songs = res.data
})
clearInterval(timer) //清除定时器
}
}, 10)
这里通过增加一个标志位确实达到了A请求先于B请求,但是付出的代价是占用了更多的浏览器资源。我们来换一种写法,
var songs = []
var songList = []
//A请求
ajax.get({
methods: 'GET',
url: '/songList'
}).then((res) => {
songList = res.data
ajax.get({
methods: 'GET',
url: '/songs',
query: {song: songList[0] }
}).then((res) => {
songs = res.data
})
})
尼玛?成了!你不是不知道运行顺序吗?我把你吃了总可以了吧,我就是要当你爸爸,“段坤我吃定了,我说的”,巧妙的运用嵌套循环就可以解决问题。所以问题解决了吗?还有没有更好的方法?
问题来了,如果B请求下还有C请求,C请求下还有D请求,D请求下还有E请求,E请求下还有F请求…没问题,我都吃了,问题是真的能吃下?当嵌套越深,你会发现代码显的十分的“臃肿”,一口吃成死胖子的赶脚。比如说代码写出来是这样的
请自行脑补…
正是为了解决这个问题,我们的前辈们呕心沥血、创造性的提出了promise函数,promise函数由此第一次走上了历史的舞台,揭示了…,发挥了…,请自行脑补…
var songs = []
var songList = []
//A请求
new Promise(() => (resolve, reject) {
ajax.get({
methods: 'GET',
url: '/songList'
}).then((res) => {
songList = res.data
resolve(songList[0]) //执行成功时,执行resolve回调
}).catch(error => {
reject(error) //执行失败时,执行reject回调
})
}).then(data => {
//B请求
ajax.get({
methods: 'GET',
url: '/songs',
query: {song: data }
}).then((res) => {
songs = res.data
})
}).catch(error => {
console.log(error)
})
在异步处理失败和成功时,Promise均会给开发者提供相应的回调函数以编写业务逻辑,这是一种成熟的解决异步嵌套的机制,而且代码看起来更整洁。也许不久的将来,我们又发现这样的机制还不够好,说不定下一个吃螃蟹的人就是你!谁说不是呢?
在异步处理失败和成功时,Promise均会给开发者提供相应的回调函数以编写业务逻辑,这是一种成熟的解决异步嵌套的机制,而且代码看起来更整洁。也许不久的将来,我们又发现这样的机制还不够好,说不定下一个吃螃蟹的人就是你!谁说不是呢?