关于Promise的文章一搜一大把,我就不写了,总结一下自己看了几篇文章的收获
1.Promise是一种规范,ES6的Promise是其中的一种实现,JQ的Deferred也是其中的一种实现,并且ajax的success和error对应了Deferred对象的done和fail(所以我ajax的error老写成fail)
2.fetch也是一个Promise对象,Promise的race方法可以用来给fetch增加timeout,all方法可以执行多个Promise,fetch的默认头和post的提交格式要注意,还有cookie
3.都说Promise解决了回调地狱,怎么解决的呢,个人理解,原本是这样的代码
function(data1, cb1){
function(data2, cb2){
function(data3, cb3){
}
}
}
通过Promise之后,可以写成这样
Promise1((resolve1, reject1) => {
resolve1();// 或者reject1();
}).then(
Promise2((resolve2, reject2) => {
resolve2();// 或者reject2();
})
)
.then()
.then()
.catch()
有多个异步操作可以全都往then里添
4.new出来的Promise是直接执行的,可以在控制台里试一下
var p = new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(123);
});//这里会打印字符串
new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(123);
});//这里会打印字符串,外加打印一个Promise对象
var p = new Promise(function (resolve, reject) {
console.log('start new Promise...');
resolve(123);
});
p.then(function () {
console.log('then');
})//这里会先打印start new Promise...,再打印then,然后再打印一个Promise对象,
//可以看出是then和Promise构造函数会返回一个新的Promise对象,这样就可以链式操作了
2018-05-06:
注意,Promise的then定义的回调是会在当前脚本的所有同步任务执行完才会执行的,可以测试下下面的代码,
let promise = new Promise(function(resolve, reject) {
console.log('Promise');
resolve();
});
promise.then(function() {
console.log('resolved.');
});
console.log('Hi!');
for(var i=100000;i--;){
for(var j=1000;j--;){
var b = '1234567890'+'asdasdasdasd';
}
}
5.all是用在多个Promise都完成的情况下
var p1 = new Promise(function (resolve, reject) {
resolve();
});
var p2 = new Promise(function (resolve, reject) {
resolve();
});
// 在p1和p2都完成后执行then:
Promise.all([p1, p2]).then(function (results) {
console.log(results);
});
6.race可以看得出是用在某个Promise先完成的情况下
贴一个增加了超时的fetch
export const get = (options, url, cb) => {
return Promise.race([ //这里用到了race
fetch(encodeURI(env.host + url) + params(options.body), {
method: 'GET',
credentials: "include"
}),
new Promise((resolve, reject) => {
setTimeout(() => reject(new Error('request timeout')), options.overtime ? options.overtime : 10 * 1000);
})
]).then(checkStatus).then((data) => {
cb(data)
}).catch((err) => {
catchErr(err,options);
});
}
7.如果 Promise 状态已经变成resolved,再抛出错误是无效的。
以下参考
http://es6.ruanyifeng.com/?search=for+of&x=0&y=0#docs/promise
const promise = new Promise(function(resolve, reject) {
resolve('ok');
throw new Error('test');
});
promise
.then(function(value) { console.log(value) })
.catch(function(error) { console.log(error) });
// ok
上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
8.如果想不区分同步和异步函数,都用Promise来包装一下(方便try…catch),可以使用Promise.try,
const f = () => console.log('now');
Promise.try(f);
console.log('next');
// now
// next
// 如果不支持Promise.try函数,可以这样写
const f = () => console.log('now');
(
() => new Promise(
resolve => resolve(f())
)
)();
console.log('next');