zoukankan      html  css  js  c++  java
  • 实现nodejs的promises库(基于promise.js改写)

    原promise.js库地址:https://github.com/stackp/promisejs

    promises是JavaScript实现优雅编程的一个非常不错的轻量级框架。该框架可以让你从杂乱的多重异步回调代码中解脱出来,并把精力集中到你的业务逻辑上。

    今天从GIT源码库中下载了promise.js,发现该源码是基于Web前端JavaScript写的,并不能直接用于nodejs。还好代码不是很多,也不是很复杂。经过分析整合,将其实现为nodejs的一个框架,代码如下:

    (function(){
    /**
    * Copyright 2012-2013 (c) Pierre Duquesne <stackp@online.fr>
    * script: promise.js
    * description: promises的nodejs模块
    * modified: https://github.com/stackp/promisejs
    * authors: alwu007@sina.cn
    * */

    var Promise = exports.Promise = function(){
        this._callbacks = [];
    };

    Promise.prototype.then = function(func, context){
        //处理回调结果的方法
        function doCallbackResults(r) {
            if (r instanceof Promise) {
                r.then(function(err, values){
                    p.done(err, values);
                });
            } else {
                p.done(null, r);
            }
        }

        var p = new Promise();
        if (this._isdone) {
            var results = func.apply(context, this.results);
            doCallbackResults(results);
        } else {
            this._callbacks.push(function(){
                var results = func.apply(context, arguments);
                doCallbackResults(results);
            });
        }
        return p;
    };

    Promise.prototype.done = function(){
        this.results = arguments;
        this._isdone = true;
        for (var i=0; i<this._callbacks.length; i++) {
            this._callbacks[i].apply(null, arguments);
        }
        this._callbacks = [];
    };

    Promise.join = function(promises){
        var p = new Promise();
        var results = [];

        if (!promises || !promises.length) {
            p.done(results);
            return p;
        }

        var numdone = 0;
        var total = promises.length;

        function notifier(i) {
            return function() {
                numdone += 1;
                results[i] = Array.prototype.slice.call(arguments);
                if (numdone === total) {
                    p.done(results);
                }
            };
        }

        for (var i = 0; i < total; i++) {
            promises[i].then(notifier(i));
        }

        return p;
    };

    Promise.chain = function(funcs, args) {
        var p = new Promise();
        if (!funcs || !funcs.length) {
            p.done.apply(p, args);
        } else {
            funcs[0].apply(null, args).then(function(){
                funcs.splice(0, 1);
                Promise.chain(funcs, arguments).then(function(){
                    p.done.apply(p, arguments);
                });
            });
        }
        return p;
    };
    })();

    另附测试代码如下:

    /**
    * script: test.js
    * description: promise.js测试代码
    * */

    var promise = require('./mypromise');

    function asyncfoo() {
        var p = new promise.Promise();
        setTimeout(function(){
            p.done();
        }, 1000);
        return p;
    }

    function syncfoo() {
        var p = new promise.Promise();
        p.done();
        return p;
    }

    var o = {};
    /*
    asyncfoo().then(function(){
        return 'Raymond';
    }, o).then(function(err, name){
        o.name = name;
        return asyncfoo().then(asyncfoo).then(function(){
            return asyncfoo().then(asyncfoo).then(function(){
                return 18;
            });
        });
    }, o).then(function(err, age){
        o.age = age;
        return asyncfoo().then(asyncfoo).then(function(){
            return asyncfoo().then(asyncfoo).then(function(){
                return 'boy';
            });
        }).then(function(err, sex){
            return sex;
        });
    }).then(function(err, sex){
        o.sex = sex;
        return 'Hello, world!';
    }).then(function(err, say){
        o.say = say;
        console.dir(o);
    });

    syncfoo().then(function(){
        return 'Raymond';
    }, o).then(function(err, name){
        o.name = name;
        return syncfoo().then(syncfoo).then(function(){
            return syncfoo().then(syncfoo).then(function(){
                return 18;
            });
        });
    }, o).then(function(err, age){
        o.age = age;
        return asyncfoo().then(asyncfoo).then(function(){
            return asyncfoo().then(asyncfoo).then(function(){
                return 'boy';
            });
        }).then(function(err, sex){
            return sex;
        });
    }).then(function(err, sex){
        o.sex = sex;
        return 'Hello, world!';
    }).then(function(err, say){
        o.say = say;
        console.dir(o);
    });
    */
    function asyncfoo1(){
        var p = new promise.Promise();
        setTimeout(function(){
            p.done(null, 'Raymond');
        }, 1000);
        return p;
    }

    function asyncfoo2(err, name){
        o.name = name;
        var p = new promise.Promise();
        setTimeout(function(){
            p.done(null, 18);
        }, 1000);
        return p;
    }
    function asyncfoo3(err, age){
        o.age = age;
        var p = new promise.Promise();
        setTimeout(function(){
            p.done(null, 'boy');
        }, 1000);
        return p;
    }
    function asyncfoo4(){
        var p = new promise.Promise();
        setTimeout(function(){
            p.done(null, 'Hello, world!');
        }, 1000);
        return p;
    }
    promise.Promise.chain([asyncfoo1, asyncfoo2, asyncfoo3]).then(function(err, sex){
        o.sex = sex;
        return asyncfoo4();
    }).then(function(err, say){
        o.say = say;
    }).then(function(){
        console.dir(o);
    });

  • 相关阅读:
    AutoMapper bool与string互转
    Self-signed SSL certificates are being blocked
    Visual Studio 2019设置自定义头部注释
    用多进程同步方法演示“桔子-苹果”问题
    实验教学管理系统 c语言程序代写源码下载
    模拟游客一天的生活与旅游java程序代写源码
    Java作业代写
    快餐店运行模拟C++程序源码代写
    hadoop-2.0.0-cdh4.2.1安装手册
    CDH4 HA方案
  • 原文地址:https://www.cnblogs.com/alwu007/p/3475226.html
Copyright © 2011-2022 走看看