scriby / asyncblock Goto Github PK
View Code? Open in Web Editor NEWSynchronous style code in an asynchronous world
License: MIT License
Synchronous style code in an asynchronous world
License: MIT License
Hi. I'm trying this:
fs = require('fs');
asyncblock = require('asyncblock');
asyncblock.enableTransform();
asyncblock(function(flow) {
var content = fs.readFile("/etc/passwd", "utf-8").sync();
console.log(content);
});
Console says:
TypeError: Cannot call method 'sync' of undefined
What can be wrong?
When transforming a source file that uses an object key named "comment", the parser spits out a mangled line. For example:
{
...
reason: request.param("reason"),
comment: request.param("comment"),
userInfo: request.sessionHelper.getUserInfo()
...
}
gets transformed to:
{
...
reason: request.param("reason"),
//call,dot,name,request,param,,,string,comment
userInfo: request.sessionHelper.getUserInfo()
...
}
Fortunately for this case the line number changes as well. However, I've seen this other places as well (after knowing what to look for), and it can happen without affecting the line numbers too.
What if I could pass informations to doneAdding() and add()?
I mean this:
asynchronous(function(){
var doc = {foo : bar};
flow.doneAdding(doc);
});
console.log(flow.forceWait()); // Output {foo : bar}
Thanks for your last modifications and good holly days for you!
I'm trying to re-use an existing asyncblock scope to avoid sprinkling a new scope in every function that needs to call async APIs and to support blocking calls. The module.exports.getCurrentFlow seems to be what I need. Is getCurrentFlow() officially supported?
"use strict";
console.log("main start");
console.time("main finish");
let asyncblock = require("asyncblock");
//let optionForceError = true;
let optionForceError = false;
function nonblockingRoutine (done) {
if (optionForceError)
setTimeout(() => done(new Error("something bad happened"), "test data"), 1000);
else
setTimeout(() => done(null, "test data"), 1000);
}
function blockingRoutine () {
console.log(" blockingTest 1");
let flow = asyncblock.getCurrentFlow();
nonblockingRoutine(flow.add());
let result = flow.wait();
console.log(" blockingTest 2");
return result;
}
asyncblock((flow) => {
console.log(" enter level 1");
try {
let result = blockingRoutine();
console.log(" result A = " + JSON.stringify(result));
} catch (e) {
console.log(" caught exception:", e.stack);
}
console.log(" leave level 1");
});
console.timeEnd("main finish");
When I try to store the results of a deferred call in a hash, I'm getting the value of the deferred object rather than the result it points to. Here's a simple program to demonstrate what's happening:
(function() {
var fs = require("fs");
var asyncblock = require("asyncblock");
if (asyncblock.enableTransform(module)) {
return;
}
asyncblock(function() {
var synced = fs.readFile(__filename, 'utf8').sync();
var deferred = fs.readFile(__filename, 'utf8').defer();
var hash = {};
hash.sync = synced; // this works just fine
hash.defer = deferred; // this doesn't work
console.log(hash);
console.log(deferred); // this works just fine too
var d = deferred; // using an intermediate works
hash.defer = d;
console.log(hash);
});
})();
Here's the suspicious output from the hash assignment:
defer:
{ _flow:
{ _parallelCount: 1,
_parallelFinished: 0,
_fiber: [Object],
_taskQueue: [],
_forceWait: false,
_light: true,
_finishedTasks: {},
errorCallback: null,
taskTimeout: null,
timeoutIsError: null,
_originalError: [Error],
_parentFlow: undefined,
_isGenerator: false,
maxParallel: 0,
firstArgIsError: true },
_key: '__defaultkey__',
_result: null,
_resultObtained: false } }
npm 1.1.6 introduces os checking, which breaks fibers <= 0.6.4. Upgrading to fibers 0.6.5 will fix the issue.
I'm using the following code, which works great:
module.exports = {
'bla': function() {
var flow = asyncblock.getCurrentFlow();
an.asyncCall('params', flow.add('a'));
return flow.get('a');
}
};
It might be nice to enable Transforms and use something like this:
module.exports = {
'bla': function() {
return an.asyncCall('params', flow.add('a')).sync();
}
};
But since the exports are not wrapped in an asyncblock, the sync
call doesn't get transformed and the result is TypeError: an.asyncCall(...).sync is not a function
Since this all lives in an Express app, my asyncblock gets launched elsewhere, but if I do explicitly wrap the exports in an asyncblock in order to force the transform, I get this:
/bla/node_modules/asyncblock/lib/flow_fiber.js:26
this._fiber.run(task);
^
TypeError: Cannot set property '_asyncblock_flow' of null
at fiberContents (/bla/node_modules/asyncblock/lib/asyncblock.js:88:32)
Am I doing something wrong? Is there another way/is it possible to enable Transforms?
:P
Hello friend!
Awesome work whit this module, I think this is not an issue, just a question.
Can you check http://goo.gl/bIvKw and try to help me?
Thanks!
in 2.2.4, I'm getting the following error:
[dtsgen] Error: Cannot find module 'fibers'
[dtsgen] at Function.Module._resolveFilename (module.js:336:15)
[dtsgen] at Function.Module._load (module.js:278:25)
[dtsgen] at Module.require (module.js:365:17)
[dtsgen] at require (module.js:384:17)
[dtsgen] at /Users/arthur/code/shopstyle-node-boilerplate/node_modules/asyncblock/lib/asyncblock.js:13:23
[dtsgen] at handleFiber (/Users/arthur/code/shopstyle-node-boilerplate/node_modules/asyncblock/lib/asyncblock.js:95:21)
[dtsgen] at asyncblock (/Users/arthur/code/shopstyle-node-boilerplate/node_modules/asyncblock/lib/asyncblock.js:28:16)
[dtsgen] at module.exports (/Users/arthur/code/shopstyle-node-boilerplate/node_modules/asyncblock/lib/asyncblock.js:44:5)
[dtsgen] at processGenerate (/source/cli.ts:36:3)
[dtsgen] at Object.<anonymous> (/source/cli.ts:31:3)
i'm no expert, so if this doesn't look like you're issue, sorry.
I see you're last commit changed from fibers to fibers-scriby, but appears that something is still looking for fibers?
Faster than uglify parser and has support for location tracking
Show an example Express application using asyncblock
Hello. I was in trouble with asyncblock (using source transformation), and I found the minimum case that couldn't work well. Do I make any mistakes?
Here is the codes.
// foo.js
var asyncblock = require('asyncblock');
if (asyncblock.enableTransform(module)) {
return;
}
asyncblock(function() {
var ary = getArray().sync();
var num = getNum().defer();
var unused1 = getNum().sync();
var unused2 = plus1(num).defer();
// console.log(num); // it becomes to work if this line is activated
ary.push(num);
console.log(ary); // [1, 2, 3] is the desired result
});
function getArray(callback) {
setImmediate(function() {
callback(null, [1, 2]);
});
}
function getNum(callback) {
setImmediate(function() {
callback(null, 3);
});
}
function plus1(num1, callback) {
setImmediate(function() {
callback(null, num1 + 1);
});
}
And when I run node foo.js
, the following error occurs.
foo.js:30
callback(null, num1 + 1);
^
TypeError: undefined is not a function
at Object._onImmediate (foo.js:30:9)
at processImmediate [as _immediateCallback] (timers.js:330:15)
I think it is a minimum case because it becomes to work if either unused variable is removed, either defer()
is changed to sync()
, or function plus1
's 1st argument is removed.
I use asyncblock 2.1.20 (the newest for now), node 0.10.24.
Sorry for my bad English. Thanks.
When a function call occurs with .sync() we know it must finish before continuing the current program flow. So, any asyncblocks created directly within the original fiber can reuse the fiber without altering program results.
asyncblock(function(){
}, callback);
In the above example, callback(undefined) will be called instead of callback(). It's probably better to call the callback with no arg at all in this case.
Could you please make asyncblock not to rely on "node" command?
Post here if you're using either of those and need help transitioning to the syntax transform methods (.sync(), .defer(), .future())
Hey, I noticed an interesting issue as illustrated below:
asyncblock(function(flow) {
var foo = function(callback) {
flow.sync.doSomething();
callback();
};
foo(flow.add());
flow.wait();
});
It seems the flow.wait pauses indefinitely. Should I expect to be able to make a sync call within an add/wait scenario?
--wampleek
A have a library that returns Q promises to make async callbacks a little easier to use on clients. However, I have a use case where I need to block and wait for the promise to be fulfilled.
I'd like to use asyncblock to achieve this, but I can't figure out how to get it to work with promises.
For example, i'd like to use it to block the return from the following function until the last promise has been fulfilled.:
function authenticate() {
return getUsername()
.then(function (username) {
return getUser(username);
})
// chained because we will not need the user name in the next event
.then(function (user) {
return getPassword()
// nested because we need both user and password next
.then(function (password) {
if (user.passwordHash !== hash(password)) {
throw new Error("Can't authenticate");
}
});
})
.done();
// HERE i'd like to block and not return from authenticate() until the last promise has been fulfilled
}
It appears that fibers has revved versions and the older v1.0.6 is now "gone forever".
See: laverdet/node-fibers#244
This obviously breaks things...
Hey, I've been using asyncblock for a couple weeks now, and I love the concise syntax. Recently I ran into a situation where I would like to have n parallel execution threads going at once. I've settled on something like:
for(var i = 0; i < numberOfExecutions; i++) {
doTask(flow.add());
if(i % 10 === 0) {
flow.wait();
}
}
flow.wait();
This works somewhat well. It will kick off 10 tasks at once, but will wait for all 10 to complete before issuing new tasks. It would be nice if I could have 10 tasks going at once until they all complete. What do you think?
Hello,
I'm using you library, but with "use strict" enabled, my node module always throws
Fatal error: Illegal access to a strict mode caller function.
If I remove "use strict" all works fine.
So I guess your lib won't work with "use strict"?
I'm using the latest node.js version.
BR,
mybecks
File lib/flow.js
contains global leaks for variables fn
and fiber
in function errorHandler
:
var errorHandler = function(self, task){
if(task != null && task.result && task.result[0] && task.firstArgIsError){
if(!task.ignoreError) {
// Some code removed...
fn = null;
fiber = null;
throw task.error;
}
}
};
I'm trying to integrate your module with an interactive solution.
I'm colliding with an error:
/home/gianfri/Scrivania/Synthia_0.2/proto2/synthia/bin/lib/asyncblock/asyncblock/lib/flow_fiber.js:26
this._fiber.run(task);
^
TypeError: Cannot set property '_asyncblock_flow' of null
at fiberContents (/home/gianfri/Scrivania/Synthia_0.2/proto2/synthia/bin/lib/asyncblock/asyncblock/lib/asyncblock.js:88:32)
in the non-interactive version it works perfectly but in the interactive one it gives me this problem
I try to explain how it works
we have an opening process that at a certain point launches
this.synchronizer ((line) => {
...
}
like ab(function(flow) { ... }
at some point I define a context with
this._iVm = require('vm'),
this._isandbox = require('vm').createContext({
require: require,
process:process,
console: console,
module:module,
app: this,
global:global,
})
then I execute my instruction in my sandbox
this._iVm.runInContext(this._iteraction.buffer.join("\n"), this._isandbox);
from the same problem even if I use require('vm').runInThisContext(...)
repeat it works correctly until I try to use the module, but only in the interactive version.
some idea?
(I also tried with the normal version 'node -i' and the probema is the same)
If require statement has a plus sign in it, the parser seems to break.
If an enumerator isn't fully exhausted, the fiber doesn't appear to be getting garbage collected.
See if there's anything we can do about this, and at the very least add an "abort" method to clean up the enumerator without moving all the way through it.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.