首先建议大家先看看这篇博文,这是我看过的最清晰给力的博文了:
https://www.cnblogs.com/lvdabao/p/es6-promise-1.html
Promise 是ES6中最重要的特性?
确实如此。让回调更加优雅。
我的第一家公司用 jQuery,第二家公司用 async/await,第三家公司使用 jQuery 和 Promise。
比较而言,我还是最喜欢 使用 async/await,不过当时也有很多别人写的UI组件,用的是 Promise,想想,出的比ES6早,在ES6被官方认证,使用者应该还是占上风的。
1.Promise有啥方法?
看一下上面的博文,通过 consle.dir(Promise)
-> Promise 是一个构造函数。
- 自身拥有的方法
- all (取时间最长的)
- reject
- resolve
- race (竞赛,取时间最短的)
- 原型链上的方法
- catch -> async/await 中需要直接用 try .. catch 来是想,算是 ES6 优胜的一点了
- then -> 不用 callback,像 jQuery 的 always/fail/done/then
既然原型链上有方法,那么 new 出来,就能够获得这些方法
let p = new Promise((resolve, reject) => {
// 一些异步操作
setTimeout(() => {
console.log('执行完成');
resolve('将数据遗留给后人');
}, 1000);
});
可以看到,这里的 函数直接自己执行了!!! 我们只是定义了一个对象,确是自己执行。
2.Promise 如何使用?
So,我们需要在它外面封装一层函数。
const Invoke = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('执行完成');
resolve({name: 'Jobs'});
}, 2000);
});
};
Invoke();
通过 Invoke 函数,我们实现了 它的该出手时就出手。
接下来,体验一下 不用 callback 地薪火相传。 无限回调地狱,再见啦。
Invoke().then((data) => {
console.log(data);
});
用 callback 实现一下
const fuckPromise = (callback) => {
setTimeout(() => {
console.log('先实现一个小目标');
callback({name: 'Jobs'});
}, 1000);
};
fuckPromise((data) => {
console.log(data);
});
对比一下: 我将他们分为 前置操作 和 后续操作。
相同点
- 两者的 后续操作,都作为参数被传递
不同点
- Promise 前置操作 中返回了一个对象,并且其中有, resolve/reject 来控制数据的传递。
- Callback 前置操作 中则是 在内部调用了 方法参数。把数据完全交给 callback 来控制。
- Promise 的后续操作,使用
Promise.then()
写在里面 - Callback 的后续操作,使用
外部函数(内部函数)
当层级一多,前者就是一堆 then,而后者??? 举个例子!!
3.从 callback 到 Promise.
Callback 版本1,当回调更多的时候,我们就能 很明显地感受到 还好我没用4格缩进
let fuckCallback = () => {
setTimeout(() => {
console.log('峰哥峰哥,');
setTimeout(() => {
console.log('影魔王');
}, 1000);
}, 1000);
}
fuckCallback();
Callback 版本2: 封装一下,缩进代码确实没有那么乱了,不过数据量大的时候还是不够 直观。
let callbackOne = (callback) => {
setTimeout(() => {
console.log('峰哥峰哥');
callback();
}, 1000);
};
let callbackTwo = (callback) => {
setTimeout(() => {
console.log('峰哥牛逼');
callback();
}, 1000);
};
callbackOne(() => {
callbackTwo(() => {
console.log('也许我是下一个操作');
});
});
Promise 版本: 代码没有往后延了,是的,这就是 Promise 的作用。看起来好像没卵用?只是量不够大而已。
const stepOne = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve('峰哥峰哥,');
}, 1000);
});
};
const stepTwo = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve('影魔王!');
}, 1000);
});
};
stepOne()
.then((data) => {
console.log(data);
return stepTwo();
})
.then((data) => {
console.log(data);
});
这里,我发现了一点,其实 Promise 并不关系你如何处理数据,你一开始,只需要负责,把Promise这个传承的能力执行下去就行了。
让我想起《我的英雄学院》这个动画里。 One for All 的能力,只需要传承即可。传承什么力量由当代决定。
4.Promise 的其他用法
- 直接 return 数据会怎么样?
let wrap = () => {
return new Promise(resolve => {
resolve({name: 'jobs'});
});
};
wrap()
.then(data => {
console.log(data);
return data;
})
.then(data => {
console.log('我再传', data);
});
- reject 和 catch 的用法
let testReject = () => {
return new Promise((resolve, reject) => {
const head = Math.random();
if (head > 0.5) {
reject('yyf头太大了');
} else {
resolve('千军万马避蓝猫');
}
});
}
testReject()
.then(data => console.dir(data))
.catch(e => console.error(e));
- all 的用法 (两者之中取 执行时间最长的那个 --> 同时执行,一般用来节省请求的时间)
let p1 = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('我会执行两秒钟');
resolve();
}, 2000);
});
};
let p2 = () => {
return new Promise((resolve) => {
setTimeout(() => {
console.log('我会执行一秒钟');
resolve();
}, 1000);
});
};
Promise
.all([p1(), p2()])
.then(() => console.log('他们都 resolve了,共计时 2s'));
切记: Promise.all([arg1,arg2,...]) 是等里面 都 resolve() 才返回。
没有 resolve 参数,那是不行的。 你会发现 promise.all.then 失效了。
- race -> 竞赛,第一个 resolve 了,则进行 then 操作,第二个还是会继续执行就是了
Promise
.race([p1(), p2()])
.then(() => console.log('看看过了几秒?'));
总结:(引用了开篇的那个文章,抄那边的)
ES6 Promise的内容就这些吗?是的,能用到的基本就这些。
我怎么还见过done、finally、success、fail等,这些是啥?这些并不在Promise标准中,而是我们自己实现的语法糖
需要继续跟进一下最顶上链接的 博客。
- Promise/A+规范
- jquery中的Promise