Blog

Blog

PHODAL

NodeJS Multiple Callback解决之使用Q Promises

在上一篇《Javascript Promises模式——相当酷的Callback Hell终结者》 我们介绍了Javascript的Promise模式,接着我们就把Javascript Promise用到我们的代码中。

JavaScript Promise库 Q

之前试着用过Q,但是没有成功。或者说,在那时候不需要用上Q,所以没有深究。现在抱着学习的态度,重新试了一下,效果还不错。

A tool for making and composing asynchronous promises in JavaScript

Q是一个提供制作和创作异步Promise的JavaScript工具。Q 提供了一些辅助函数,可以将Node和其他环境适配为promise可用的。

JavaScript Promise库 Q示例

官网给了一个简单的转换的例子

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

将他转换为

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();

但是,我们没有看懂,我们到底做了些什么。。

JavaScript Promise 库 Q实战

原生的代码是这样子的,用的是async库

async.parallel([
    function () {
        'use strict';
        pr.get(domain, next);
    },

    function () {
        'use strict';
        gs.get(name, next);
    },

    function () {
        'use strict';
        csdn.get(name, next);
    },

    function () {
        'use strict';
        zhihu.get(name, next);
    },

    function () {
        'use strict';
        alexa.get(domain, next);
    }
]);

但是总感觉写得有点乱,不过至少离开了所谓的回调大坑。

过程大致上就是当我们需要不断往我们的result里面添加东西。

于是将代码改成Promise的形式,接着就变成这样了

github.promise_get(response, name)
    .then(function (result) {
        return pr.promise_get(result, domain);
    })
    .then(function (result) {
        return csdn.promise_get(result, name);
    })
    .then(function (result) {
        return zhihu.promise_get(result, name);
    })
    .then(function (result) {
        return alexa.promise_get(result, domain);
    })
    .then(function (result) {
        callback(result);
    });

但是这样看上去写得有点不好,因为我们将过程固化在代码中,于是试着,用别的方法对其重构。

重构的第一步后就变成这样子

var info = Information.prototype;

info.pageRank_get = function(result){
    'use strict';
    return pageRank.promise_get(result, Information.prototype.domain);
};

info.alexa_get = function(result){
    'use strict';
    return alexa.promise_get(result, Information.prototype.domain);
};

info.csdn_get= function (result) {
    'use strict';
    return csdn.promise_get(result, info.name);
};

info.github_get= function (result) {
    'use strict';
    return github.promise_get(result, info.name);
};

info.zhihu_get = function (result) {
    'use strict';
    return zhihu.promise_get(result, info.name);
};

info.initVal = function (result) {
    'use strict';
    result = [];
    return result;
};

Information.prototype.get = function (callback) {
    'use strict';
    Q.fcall(info.initVal)
        .then(info.github_get)
        .then(info.csdn_get)
        .then(info.zhihu_get())
        .then(info.pageRank_get)
        .then(info.alexa_get)
        .then(function (result) {
            callback(result);
        });
};

先提出每一个方法,然后我们就可以选择我们需要用到的库。看上去比上面整洁多了,但是我们还需要下一步,以便继续。

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806

新书《前端架构:从入门到微前端》

《前端架构:从入门到微前端》是一本围绕前端架构的实施手册,从基础的架构规范,到如何设计前端架构,再到采用微前端架构拆分复杂的前端应用。本书通过系统地介绍前端架构世界的方方面面,来帮助前端工程师更好地进行系统设计。

前端架构包含以下五部分内容:

  • 设计:讲述了架构设计的模式,以及设计和制定前端工作流。
  • 基础:通过深入构建系统、单页面应用原理、前端知识体系等,来构建出完整的前端应用架构体系。
  • 实施:通过与代码结构的方式,介绍如何在企业级应用中实施组件化架构、设计系统和前后端分离架构。
  • 微前端:引入6种微前端的概念,以及如何划分、设计微前端应用,并展示了如何实现这6种微前端架构。
  • 演进:提出更新、迁移、重构、重写、重新架构等架构演进方式,来帮助开发人员更好地设计演进式架构。
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Developer, Consultant, Writer, Designer

ThoughtWorks 高级咨询师

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 与我沟通

标签