J'ai téléchargé promise.js à partir de la bibliothèque de code source GIT aujourd'hui et j'ai découvert que le code source est écrit sur la base de JavaScript frontal Web et ne peut pas être utilisé directement pour nodejs. Heureusement, il n’y a pas beaucoup de code et ce n’est pas très compliqué. Après analyse et intégration, il est implémenté comme framework de nodejs. Le code est le suivant :
(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; }; })();
Ci-joint le code du test comme suit :
/** * 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); });