Promise
- 主要用于异步计算,
- 可以将异步操作队列化,按照期望的顺序执行,返回符合预期的结果,避免了回调地狱的发生
- 可以在对象之间传递和操作promise,帮助我们处理队列
状态
- pending:初始状态
- fulfilled:操作成功
- rejected:操作失败
tips
- Promise实例一经创建,执行器立即执行
- .then()返回
新的promis实例,(注意,不是原来那个Promise实例) - 调用resolve或reject并不会终结 Promise 的参数函数的执行
new Promise((resolve, reject) => {
resolve(1);
console.log(2);
}).then(r => {
console.log(r);
});
// 2
// 1
- 一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。
new Promise((resolve, reject) => {
return resolve(1);
// 后面的语句不会执行
console.log(2);
})
Promise的基本使用和原理
- 在.then()中返回新的promise实例
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 2000);
}).then(value => {
console.log(value)
return new Promise(resolve => {
setTimeout(() => {
resolve('world')
}, 2000)
})
}).then(value => {
console.log(value + 'world')
})
- 如果Promise.then()的函数里不返回新的Promise会怎么样
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
}, 2000);
}).then(value => {
console.log(value);
//立即执行函数
(function () {
return new Promise(resolve => {
setTimeout(() => {
console.log('mr.laurence')
resolve('world')
}, 2000)
})
})();
return false
}).then(value => {
console.log(value + 'world')
})
3. .then()里的新声明的promise里有.then()的时候,会等到里面的.then()执行完毕,在执行外面的。
let p = new Promise(resolve => {
console.log('Step 1')
setTimeout(() => {
resolve(100)
}, 1000);
}).then(value => {
return new Promise(resolve => {
console.log('Step 1-1')
setTimeout(() => {
resolve(110)
}, 1000);
}).then(value => {
console.log('Step 1-2')
return value
}).then(value => {
console.log('Step 1-3')
return value
})
}).then(value => {
console.log(value)
console.log('Step 2')
})
测试
文章:we have a problem with promises
- 在then中返回另有一个promise实例
doSomething().then(function(){
return doSomethingElse()
}).then(finalHandler)
- then中没有返回值
doSomethiing().then(function(){
doSomethingElse()
}).then(finalHandler)
3.如果then方法接受的不是一个函数,会返回一个空的promise对象,这个promise会被忽略
promise.then(onFulfilled,onRejected) 文档中有明确说明,如果onFulfilled,onRejected这个两个参数都被遗漏或者非函数,会被忽略
doSomething().then(doSomethingElse())
.then(finalHandler)
4.
doSomethiing().then(doSomethingElse)
.then(finalHandler)
错误处理
- Promise会自动捕获异常,并交给rejected响应函数
练习
Generator
Promise的应用
三张图片都加载完了之后再渲染到页面
// 所有图片加载完再添加到页面
function loadImg (src) {
return new Promise((resolve, reject) => {
let img = document.createElement('img')
img.src = src
//图片加载完成
img.onload = function () {
resolve(img)
}
//图片加载失败
img.onerror = function (error) {
reject(error)
}
})
}
function showImg (imgs) {
imgs.forEach(function (img) {
document.body.appendChild(img)
})
}
// 多个promise实例
Promise.all([
loadImg('http://i4.buimg.com/567571/dflef0720bea6832.png'),
loadImg('http://i4.buimg.com/567571/dflef0720bea6832.png'),
loadImg('http://i4.buimg.com/567571/dflef0720bea6832.png')
]).then(showImg)
面试题
将原生的ajax封装成promise
function newAjax (method,url){
const p = new Promise(function(resolve,reject){
let xhr = XMLHttpRequest ? new XMLHttpRequset() : new ActiveXObject()
xhr.onreadysatechange = function (){
if(xhr.readyState === 4){
if(xhr.status === 200 || xhr.status === 304){
reslove(JSON.parse(xhr.responseText))
}else{
reject(new Error('not found'))
}
}
}
xhr.open('GET',url,true)
xhr.send(null)
})
}