ES6的Promise

268 阅读3分钟

在JavaScript中,所有代码都是单线程的,也就是同步执行的,而Promise为异步编程提供了一种解决方案。

什么时候会处理异步事件呢?

  • 一种很常见的场景应该就是网络请求了。
  • 我们封装一个网路请求的函数,因为不能立即拿到结果,所以不能像简单的1+2=7一样将结果返回。
  • 所以往往我们会传入另一个函数,在数据请求成功时,将数据通过传入的函数回调出去。
  • 如果只是一个简单的网络请求,那么这种方案不会给我们带来很大的麻烦。
  • 但是当网络请求非常复杂的时候,就会出现回调地狱。

回调地狱

异步JavaScript或使用回调的JavaScript很难直观地得到正确的结果。出现回调地狱的最主要原因就是自己在编写代码的过程中过于刻板,循规蹈矩,以至于不断在一层函数下接着进行第二层,已达到第二层代码的执行效果。但很明显效果事半功倍。

//回调地狱
const p = new Promise((resolve, reject) => {
    //模拟异步
    setTimeout(() => {
        console.log('第一次请求')
	console.log('第一次请求')
	console.log('第一次请求')
	console.log('第一次请求')
	console.log('第一次请求')/
					
	setTimeout(() => {
            console.log('第二次请求')
            console.log('第二次请求')
            console.log('第二次请求')
            console.log('第二次请求')
            console.log('第二次请求')
						
            setTimeout(() => {
		console.log('第三次请求')
		console.log('第三次请求')
		console.log('第三次请求')
		console.log('第三次请求')
		console.log('第三次请求')
            })
	})
    },1000)
})

Promise状态

Promise异步操作有三个状态: pending(进行中)、fulfill(已成功)和rejected(已失败)。除了异步操作的结果,任何其他操作都无法改变这个状态。
Promise对象只有: 从pending变为fulfilled和从pending变为rejected的状态改变。只要处于fulfilled和rejected,状态就不会再变了,即resolved(已成型)。

Promise的基本使用

普通调用

const a = new Promise((resolve, reject) => {
    //模拟异步
    setTimeout(() => {
        resolve()
    }, 1000)
})
const b = new Promise((resolve, reject) => {
    //模拟异步
    setTimeout(() => {
        resolve()
    }, 1000)
})
const c = new Promise((resolve, reject) => {
    //模拟异步
    setTimeout(() => {
        resolve()
    }, 1000)
})
a.then(() => {
    console.log('第一次请求')
    console.log('第一次请求')
    console.log('第一次请求')
    console.log('第一次请求')
    console.log('第一次请求')
})
b.then(() => {
    console.log('第二次请求')
    console.log('第二次请求')
    console.log('第二次请求')
    console.log('第二次请求')
    console.log('第二次请求')
})
c.then(() => {
    console.log('第三次请求')
    console.log('第三次请求')
    console.log('第三次请求')
    console.log('第三次请求')
    console.log('第三次请求')
})

多个回调

const p = new Promise((resolve, reject) => {
    //模拟异步
    setTimeout(() => {
        resolve()
    }, 1000)
}).then(() => {
    console.log('第一次请求')
    console.log('第一次请求')
    console.log('第一次请求')
    console.log('第一次请求')
    console.log('第一次请求')

    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
	}, 1000)
    })
}).then(() => {
    console.log('第二次请求')
    console.log('第二次请求')
    console.log('第二次请求')
    console.log('第二次请求')
    console.log('第二次请求')

    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve()
	}, 1000)
    })
}).then(() => {
    console.log('第三次请求')
    console.log('第三次请求')
    console.log('第三次请求')
    console.log('第三次请求')
    console.log('第三次请求')
})

链式调用

完整写法

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('这是')
    },1000)
}).then(res => {
    console.log(res)
				
    return new Promise((resolve, reject) => {
        resolve(res + '完整的')
    })
}).then(res => {
    console.log(res)
				
    return new Promise((resolve, reject) => {
        resolve(res + '一段话')
    })
}).then(res => {
    console.log(res)
})

简写

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('这是')
    },1000)
}).then(res => {
    console.log(res)
				
    return Promise.resolve(res + '完整的')
}).then(res => {
    console.log(res)
				
    return Promise.resolve(res + '一段话')
}).then(res => {
    console.log(res)
})

最简写

const p = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve('这是')
    },1000)
}).then(res => {
    console.log(res)
				
    return res + '完整的'
}).then(res => {
    console.log(res)
				
    return res + '一段话'
}).then(res => {
    console.log(res)
})

捕捉异常

在后面跟上.catch(error => console.log(error))