Yeechan Lu
イェーチャン・ルー
Yeechan Lu
使多个操作可以在重叠的时间段内进行
----------------▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇-------▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇--------------------------------------------------------------------▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇---
▇▇▇▇▇▇▇▇--------▇▇▇▇▇▇▇▇▇-----------------▇▇▇▇--------▇▇▇▇▇▇▇▇---------▇▇▇▇▇▇▇▇---------▇▇▇▇▇▇▇▇▇------------▇▇▇▇▇▇▇▇-------------------------------------------▇▇▇▇▇▇▇▇---------------------
node has non-blocking IO everywhere
— Tim Caswell
node has non-blocking IO everywhere
From: Tim Caswell <tim@creationix.com>To: nodejs@googlegroups.comSubject: Comparison between continuables, promises and many variants on them.Date: Thu, 18 Feb 2010 14:56:46 -0600There has been a lot of discussion lately about the best way to do async functions in node. This is so important because node has non-blocking IO everywhere and regular exceptions don't work in this case.Several of us in IRC made a gist to show a quick example of the different styles.https://gist.github.com/602efd6a0d24b77fda36This is a simple example, but it highlights enough of the differences to get a feel for how everything works.I think that ideally node should ship with three versions of the async io libraries. - A base library based on pure callbacks - A true sync version of that library for the times you don't care about blocking - And a "blessed" async library that wraps the base async library in Ryan's favorite of these options.The plain async library will great for us who want to do our own thing and don't want the overhead of wrapping someone else's stuff that you don't like.The sync version will be very useful for short running scripts and things that only happen at server startup.And for the node programmers who don't care what style of async code they use, but just want a common official style that's better than plain callbacks, will use the third lib.The first two libs have to be shipped with node, but third may or may not.
// synchronousfunction test_and_load(filename) { var stat = fs.statSync(filename); // Filter out non-files if (!stat.isFile()) { return; } // Otherwise read the file in return fs.readFileSync(filename)}
// simple continuable with seperate callback and errbackfunction test_and_load(filename) { return function (callback, errback) { fs.stat(filename)(function (stat) { // Filter out non-files if (!stat.isFile()) { callback(); return; } // Otherwise read the file in fs.readFile(filename)(callback, errback); }, errback);}}
// simple continuable with single combined callbackfunction test_and_load(filename) { return function (callback) { fs.stat(filename)(function (stat) { // Pass along any errors before we do anything if (stat instanceof Error) { callback(stat); return; } // Filter out non-files if (!stat.isFile()) { callback(); return; } // Otherwise read the file in fs.readFile(filename)(callback); });}}
// inimino style continuablesfunction test_and_load(filename) { return function (cont) { fs.stat(filename)(rightContinuation(cont)(function (stat) { // Filter out non-files if (!stat.isFile()) { cont(); return; } // Otherwise read the file in fs.readFile(filename)(cont); }));}}
// http://github.com/bentomas/node-continuablesfunction test_and_load(filename) { return fs.stat(filename)(function (stat) { // Pass along any errors before we do anything if(stat instanceof Error) { return; } // Filter out non-files if (!stat.isFile()) { return null; } // Otherwise read the file in return fs.readFile(filename); });}
// promise based with node-promise helpers (github.com/kriszyp/node-promise)var when = require("promise").when;function test_and_load(filename) { return when(fs.stat(filename), function (stat) { // Filter out non-files if (!stat.isFile()) { return; } // Otherwise read the file in return fs.readFile(filename); });}
// promise based with CommonJS monkey patch (github.com/kriszyp/node-commonjs/blob/master/patch-promise.js)function test_and_load(filename) { return fs.stat(filename).then(function (stat) { // Filter out non-files if (!stat.isFile()) { return; } // Otherwise read the file in return fs.readFile(filename); });}
// promise based (how it works in current node)function test_and_load(filename) { var promise = new process.Promise(); fs.stat(filename).addCallback(function (stat) { // Filter out non-files if (!stat.isFile()) { promise.emitSuccess(); return; } // Otherwise read the file in fs.readFile(filename).addCallback(function (data) { promise.emitSuccess(data); }).addErrback(function (error) { promise.emitError(error); }); }).addErrback(function (error) { promise.emitError(error); }); return promise;}
From: Ryan Dahl <coldre...@gmail.com>To: nodejs@googlegroups.comSubject: Re: [nodejs] Comparison between continuables, promises and many variants on them.Date: Fri, 19 Feb 2010 10:00:08 -0800Hey everyone,I'm going to remove promises entirely. For places where promises wouldbe used (fs, dns) I will instead use a standard callback interface: method(arg0, arg1, arg2, function (error, result0, result1) { puts('complete'); });That is, the completion callback will always be the last parameter andthe first argument the completion will always be reserved for an errorobject. By following this scheme everywhere, I'm confident that verygood user-land deferred/promise/continuation libraries will spring up.Expect this interface in the next version of node, 0.1.30.
method(arg0, arg1, arg2, function (error, result0, result1) { puts('complete');});
function doGreatWork(userId, fileName, callback) { getUser(userId, function (err, user) { if (err) return callback(err, null); getCompany(user.companyId, function (err, company) { if (err) return callback(err, null); getLocation(company.location, function (err, location) { if (err) return callback(err, null); getLatLong(location, function (err, latLong) { if (err) return callback(err, null); findSatelitteImage(latLong, 5 * km, function (err, imageUrl) { if (err) return callback(err, null); downloadImage(imageUrl, function (err, image) { if (err) return callback(err, null); writeToFile(fileName, image, function (err, result) { if (err) return callback(err, null); return callback(null, fileName) }); }); }); }); }); }); });}
By following this scheme everywhere, I'm confident that very good user-land deferred / promise / continuation libraries will spring up.
— Ryan Dahl
method(arg0, arg1, arg2).then(function(result) { puts('complete');}).catch(function(error) { puts('failed');})
function doGreatWork(userId, fileName) { return getUser(userId).then(function (user) { return getCompany(user.companyId) }).then(function(company) { return getLocation(company.location) }).then(function(location) { return getLatLong(location) }).then(function(latLong) { return findSatelitteImage(latLong, 5 * km) }).then(function(imageUrl) { return downloadImage(imageUrl) }).then(function(image) { return writeToFile(fileName, image) }).then(function() { return fileName; })}
function doGreatWork(userId, fileName) { return getUser(userId).then(function (user) { return getCompany(user.companyId) }).then(function(company) { /* I need user here */ })}
function doGreatWork(userId, fileName) { return getUser(userId).then(function (user) { return getCompany(user.companyId).then(function(company) { return user.sayHello(company); }) })}
function doGreatWork(userId, fileName) { var _user; return getUser(userId).then(function (user) { _user = user; return getCompany(user.companyId) }).then(function(company) { return _user.sayHello(company); })}
function doGreatWork(userId, fileName) { var ctx = {}; return getUser(userId).then(function (user) { ctx.user = user; return getCompany(user.companyId) }).then(function(company) { return ctx.user.sayHello(company); })}
# CoffeeScriptdo_great_work = (file_name) -> get_user(user_id).then (@user) => get_company(@user.company_id) .then (@company) => @user.say_hello(@company)
// Bluebirdfunction doGreatWork(userId, fileName) { return getUser(userId).bind({}).then(function (user) { this.user = user; return getCompany(user.companyId) }).then(function(company) { return this.user.sayHello(company); }).bind()}
function doLittleWork(name) { return uploadHighScore(getDeviceId(), name, name.length) .then(() => true) .catch(() => false)}doLittleWork("orzFly").then(() => saveAndQuit());
function doLittleWork(name) { return uploadHighScore(getDeviceId(), name, name.length) .then(() => true) .catch(() => false)}doLittleWork(undefined).then(() => saveAndQuit());// TypeError: Cannot read property 'length' of undefined// at doLittleWork (presentation.js:6:51)
co(function* () { try { let result = yield method(arg0, arg1, arg2); puts('complete'); } catch (error) { puts('failed'); })})
var doGreatWork = co.wrap(function* (userId, fileName) { var user = yield getUser(userId); var company = yield getCompany(user.companyId); var location = yield getLocation(company.location); var latLong = yield getLatLong(location); var imageUrl = yield findSatelitteImage(latLong, 5 * km); var image = yield downloadImage(imageUrl); yield writeToFile(fileName, image); return fileName;});
var doGreatWork = Promise.coroutine(function* (userId, fileName) { var user = yield getUser(userId); var company = yield getCompany(user.companyId); var location = yield getLocation(company.location); var latLong = yield getLatLong(location); var imageUrl = yield findSatelitteImage(latLong, 5 * km); var image = yield downloadImage(imageUrl); yield writeToFile(fileName, image); return fileName;});
var doGreatWork = async function (userId, fileName) { var user = await getUser(userId); var company = await getCompany(user.companyId); var location = await getLocation(company.location); var latLong = await getLatLong(location); var imageUrl = await findSatelitteImage(latLong, 5 * km); var image = await downloadImage(imageUrl); await writeToFile(fileName, image); return fileName;};
var doGreatWork = async function (userId, fileName) { let user = getUser(userId); let company = yield getCompany(user.companyId); return yield user.sayHello(company);};
var doLittleWork = async function (userId, fileName) { try { yield uploadHighScore(getDeviceId(), name, name.length); return true; } catch (e) { return false; }};doLittleWork(undefined).then(() => saveAndQuit());
new Thread(function() { console.log("Hello, threads!"); });
let result = new Thread(() => 42).join(); // returns 42
new Thread(() => 42).asyncJoin().then((result) => /* result is 42 */)
The next step for this wild thought experiment is to attempt to implement it and see if it works.
イェーチャン・ルー
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |