Promise Q async 与 Generator

Promise & Q

https://github.com/kriskowal/q

传统模式中将方法当做函数的参数,并在运行时执行.

 step1(function (value1) {
    step2(value1, function(value2) {
        step3(value2, function(value3) {
            step4(value3, function(value4) {
                // Do something with value4
            });
        });
    });
});

显而易见,回调链越长,越不直观.

我们使用 Promise 或 Q 来整理这些回调后代码会变成这样.

Q.fcall(promisedStep1)
.then(promisedStep2)
.then(promisedStep3)
.then(promisedStep4)
.then(function (value4) {
    // Do something with value4
})
.catch(function (error) {
    // Handle any error from all above steps
})
.done();

Q 和 ES2015 中的原生 Promise 作用基本一样. 都遵循 Promise A+ 规范,只不过 Promise 是原生的,我们可以继续使用 Q 来当 Promise 的 polyfill

let p = new Promise((resolve,reject)=>{
      setTimeout(n=>{
            resolve(1);
      },1000);
}).then(n=>{
      return n+1;
}).then(n=>{
      return n+2;
});

async.js

http://caolan.github.io/async/

使用 async 来处理回调可以起到相同的作用,但是他的用法不同:

比如我们可以依次执行一连串回调

var async = require("async")

async.series([
    function(callback) {
        setTimeout(n => {
            console.log(1);
            callback();
        }, 2000);
    },
    function(callback) {
        setTimeout(n => {
            console.log(2);
            callback();
        }, 1000);
    }
]);

//=> 1
//=> 2

或者使用 waterfall 来达到传值的目的.

async.waterfall([
    function(callback) {
        callback(null, 'one', 'two');
    },
    function(arg1, arg2, callback) {
        // arg1 now equals 'one' and arg2 now equals 'two'
        callback(null, 'three');
    },
    function(arg1, callback) {
        // arg1 now equals 'three'
        callback(null, 'done');
    }
], function (err, result) {
    // result now equals 'done'
});

如果要 "依次" 拼凑出一连串回调,用 async 可能会比 Promise 方便一些.

Generator

Promise 是 javascript 社区的产物, 而 Generator 是从其它语言借鉴过来的.

Generator 意为"协同器" 可以让多个线程或函数共同完成一个任务.

function* myGen(num){
    var num1 = yield num;
    console.log(num1);
}

let gem = myGen(1);
let num = gem.next().value;
gem.next(num+1)

yield 关键字后即是要抛出的变量,然后在获取这个变量后,再调用 next() 函数继续.

自动执行的 Generator:

其核心原理是: yield 后抛出一个 Promise 然后在其 then 中执行 next

"use strict";

function* myGen(){
    let g1 = yield new Promise((resolve,reject)=>{
        setTimeout(n=>{
            console.log("1");
            resolve(2);
        },1000);
    });
    let g2 = yield new Promise((resolve,reject)=>{
        setTimeout(n=>{
            console.log(g1);
            resolve(g1+1);
        },1000);
    });
    console.log(g2)
}

var gen = myGen();

gen.next().value.then(s=>{
    gen.next(s).value.then();
});

当然最后的嵌套还是有点蛋疼,我们可以写一个自动执行器:

var gen = myGen();
function run(gen){
  var g = gen();
  function next(data){
    var result = g.next(data);
    if (result.done) return result.value;
    result.value.then(function(data){
      next(data);
    });
  }
  next();
}
run(myGen);
留言:

称呼:*

邮件:

网站:

内容: