适合新手的Generator、Promise教程
发布于 2 个月前 作者 bensonlove 549 次浏览 来自 分享

适合新手的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中的返回值
    }
    

完!

3 回复

Generator 是不是就是函数队列?

一般使用p.then(onFulfilled).catch(onRejected)代替p.then(onFulfilled, onRejected)语义上更明确

回到顶部