适合新手的Generator、Promise教程
Generator和Promise是为了解决异步编程问题,在此就不长篇大论了。本篇只讨论Generator和Promise的快速使用
本篇博客github地址: https://github.com/bensonlove/blogs/blob/master/Generator%26Promise.md
综合使用案例之 koa2 + mongodb + redis爬虫程序
Generator
定义了一个Generator函数
function* G() {
yield x;
yield y;
}
关于*
号:*
号是Generator
函数的标志,也是区别于普通函数的重要特征
关于yield
:使用yield
来定义函数内部的不同状态,上述函数就有x和y两个状态,函数执行到此处时就会暂停,并返回结果
调用Generator函数
var g = G()
g1.next() //{value: x, done: false}
g2.next() //{value: y, done: true}
调用Generator函数后,该函数并不执行,返回一个Iterator对象
关于Iterator对象的内容可以查看这里
当调用next方法时, 会返回一个包含value和done两个属性的对象
- value: 表示函数内部状态的值
- done: 遍历是否结束, true表示后面没有状态了
当遍历结束再次调用next
方法时会返回{value: undefined, done: true}
Promise
定义一个Promise
var promise = new Promise(function(resolve, reject) {
if(success) resolve(value);
reject(err);
})
Promise
构造函数接收一个函数作为参数,该函数的两个参数都是函数
- resolve: 成功时调用
- reject:失败时调用
调用Promise
无需手动调用,一旦创建就会立即执行
then方法
then方法定义在Promise的原型对象上,调用then返回的是一个新的Promise对象。这也是Promise可以无限then的原因。
promise.then(function(value) {
console.log(value);
}, function(error) {
console.log(error);
});
then方法接收两个函数作为参数 ,其中第一个函数是必须的,第二个函数是可选的。
- 第一个函数对象对应上述的
resolve
函数的实现 - 第二个函数对象对应上述的
reject
函数的实现
在resolve
函数中可以return
一个值作为下一个then
方法的参数,此时return的值会被包装在promise
中,调用then方法可以取出值。
promise.then(function(value) {
return 'D.VA 爱你哟';
}).then(function(value) {
console.log(value); //输出D.VA 爱你哟
});
其他方法
- catch: 捕获异常。
- all: 将多个
promise
放在一起同时执行。当多个promise
都变成resolve
状态时才会执行then
方法。then
方法中的参数以数组形式存在,表示多个promise
的返回值
bluebird
由于ES6原生提供Promise
,所以无需安装Promise
库。但在ES5环境下我们可以使用bluebird
库来提供Promise
安装bluebird
npm install bluebird --save
使用bluebird
var Promise = require('bluebird');
var promise = new Promise(function(resolve, reject) {
if(success) resolve(value);
reject(err);
});
promise.then(function() {
console.log('天降正义'); //输出: 天降正义
});
async/await
async函数就是Generator函数的语法糖 如:
function* f() {
yield 'x';
}
//相当于
async function f() {
await 'x';
}
说白了就是async替代了Generator中的* , yield被替换成了await。
注意:
- async函数无需手动调用next方法。
-
await 后面的是一个Promise对象。上例中await后面的是一个字符x,它会被转成Promise对象。
-
await 只能在async函数内部使用,所以当在async函数内执行Promise时 不能将await放在then方法中,需要使用如下形式
async function f() { var data = await getDataPromise(url) //data就表示promise中的返回值 }
完!
Generator 是不是就是函数队列?
一般使用p.then(onFulfilled).catch(onRejected)
代替p.then(onFulfilled, onRejected)
语义上更明确