1: promise,promise有几种状态,是否可逆?
先有的 Promise 后有的 async/await,中间还有个 generator。
promise是一个异步函数,主要是为了解决异步处理回调地狱问题(循环嵌套问题),
new promise 有 3个状态pedding(等待中),fulfilled(成功状态) ,rejected(失败状态) ,一旦状态改变将不可逆,
promise.then():
返回一个新的promise对象(注意不是之前的promise实例),因此可以链式调用(可以指定一组按照次序执行的回调函数,后一个回调函数会等promise状态改变后才会被调用),then方法接收2个参数,一个resolved 状态的回调函数,一个是rejected 状态的回调函数,
promise.catch():
用来捕获异常,promise的异常会一直往下传,直到被捕获(错误总是会被下一个catch捕获),一般来说不建议在then的第二个参数来设置处理异常的回调函数,而是直接使用catch来捕获异常(1: 可以捕获promise内部异常 2: catch返回的是一个promise对象,因此可以继续执行后面的then方法)
getJSON('/post/1.json').then(function(post) {
return getJSON(post.commentURL);
}).then(function(comments) {
// some code
}).catch(function(error) {
// 处理前面三个Promise产生的错误
});
一共有三个 Promise 对象:一个由getJSON()产生,两个由then()产生。
它们之中任何一个抛出的错误,都会被最后一个catch()捕获。
-------------------------------------------------------------
案例2: 获取多个文件信息
const fs = require('fs');
const pReadFile = (filePath) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
fs.readFile(filePath, 'utf8', (error, data) => {
if (error) {
reject(error);
} else {
// 下面一行会报错,因为x没有声明
// resolve(x + 2);
resolve(data);
}
});
});
};
const pGet = (url, callback) => {
return new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest()
xhr.open('get', url) // 初始化请求
xhr.setRequestHeader() // 设置头header
xhr.send({id: 111, type: 'merchant'}) // 发送请求
xhr.onload = e => {
resolve(xhr.reponseText)
callback && callback(Json.parse(xhr.reponseText))
}
/**
xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && status === 200) {
callback && callback(Json.parse(xhr.reponseText))
}
}
*/
xhr.onerror = error => reject(error)
})
}
pReadFile('./data/a.txt')
.then(data => {
console.log('a文件数据: ' + data);
return pReadFile('./data/b.txt')
})
.catch(error => {
console.log('oh no', error);
})
.then(data => {
console.log('b文件数据: ' + data);
return pReadFile('./data/c.txt')
})
.then(data => {
console.log('c文件数据: ' + data);
return data.jobs
})
pGet('./data.json')
.then(data => {
console.log(data);
return data.jobs
})
.then(jobsData => {
let htmlStr = template('tpl', jobsData);
document.getElementById('user-form').innerHTML = htmlStr;
})
上面代码运行完catch()方法指定的回调函数,会接着运行后面那个then()方法指定的回调函数。
如果没有报错,则会跳过catch()方法
promise.finally():
指定不管promise状态如何都会执行的操作
promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});
--------------------------------
promise
.finally(() => {
// 语句
});
// 等同于
promise
.then(
result => {
// 语句
return result;
},
error => {
// 语句
throw error;
}
);
promise.all():
将多个promise实例包装成一个新的promise实例,等到全部执行完后,统一执行success
promise.race() :
将多个promise实例包装成一个新的promise实例,只要有一个完成,就执行success
const p = Promise.all([p1, p2, p3]);
p的状态由p1、p2、p3决定,
分成2种情况。
1: 只有p1、p2、p3的状态都变成fulfilled(成功状态),p的状态才会变成fulfilled,
此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。(
2: 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,
此时第一个被reject的实例的返回值,会传递给p的回调函数。
参考资料: