Skip to content
This repository has been archived by the owner on Feb 26, 2024. It is now read-only.

Commit

Permalink
feat(asynchooks): use asynchooks to handle native async/await
Browse files Browse the repository at this point in the history
  • Loading branch information
JiaLiPassion committed Jan 1, 2018
1 parent 1741e70 commit 4b52ea0
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 261 deletions.
17 changes: 9 additions & 8 deletions gulpfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,17 +314,10 @@ gulp.task('build', [
'build/closure.js'
]);

gulp.task('test/node2017', ['compile-node-es2017'], function(cb) {
var testAsyncPromise = require('./build/test/node_async').testAsyncPromise;
testAsyncPromise();
});

gulp.task('test/node', ['compile-node'], function(cb) {
function runJasmineTest(specFiles, cb) {
var JasmineRunner = require('jasmine');
var jrunner = new JasmineRunner();

var specFiles = ['build/test/node_entry_point.js'];

jrunner.configureDefaultReporter({showColors: true});

jrunner.onComplete(function(passed) {
Expand All @@ -345,6 +338,14 @@ gulp.task('test/node', ['compile-node'], function(cb) {
jrunner.specDir = '';
jrunner.addSpecFiles(specFiles);
jrunner.execute();
}

gulp.task('test/node2017', ['compile-node-es2017'], function(cb) {
runJasmineTest(['build/test/node_entry_point_es2017.js'], cb);
});

gulp.task('test/node', ['compile-node'], function(cb) {
runJasmineTest(['build/test/node_entry_point.js'], cb);
});

// Check the coding standards and programming errors
Expand Down
64 changes: 0 additions & 64 deletions lib/node/async_hooks_promise.ts

This file was deleted.

19 changes: 4 additions & 15 deletions lib/node/async_promise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,18 @@ Zone.__load_patch('node_async_hooks_promise', (global: any, Zone: ZoneType, api:
const originalThen = promise.then;

const zone = Zone.current;
if (zone.name === 'promise') {
print('init promise', id.toString());
}
if (!zone.parent) {
print('root zone');
return;
}
const currentAsyncContext: any = {};
currentAsyncContext.id = id;
currentAsyncContext.zone = zone;
idPromise[id] = currentAsyncContext;
promise.then = function(onResolve: any, onReject: any) {
const wrapped = new Promise((resolve, reject) => {
originalThen.call(this, resolve, reject);
});
if (zone) {
(wrapped as any).zone = zone;
}
return zone.run(() => {
return wrapped.then(onResolve, onReject);
const task = zone.scheduleMicroTask(PROMISE_PROVIDER, noop, null, noop);
process.nextTick(() => {
task.zone.runTask(task, null, null);
originalThen.call(this, onResolve, onReject);
});
};
}
Expand All @@ -69,22 +61,19 @@ Zone.__load_patch('node_async_hooks_promise', (global: any, Zone: ZoneType, api:
function before(id: number) {
const currentAsyncContext = idPromise[id];
if (currentAsyncContext) {
print('before ' + id, currentAsyncContext.zone.name);
api.setAsyncContext(currentAsyncContext);
}
}

function after(id: number) {
const currentAsyncContext = idPromise[id];
if (currentAsyncContext) {
print('after ' + id, currentAsyncContext.zone.name);
idPromise[id] = null;
api.setAsyncContext(null);
}
}

function destroy(id: number) {
print('destroy ' + id);
}

async_hooks.createHook({init, before, after, destroy}).enable();
Expand Down
56 changes: 56 additions & 0 deletions test/asynchooks/await.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

describe('native async/await', function() {
const log: string[] = [];
const zone = Zone.current.fork({
name: 'promise',
onScheduleTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: any) => {
log.push('scheduleTask');
return delegate.scheduleTask(target, task);
},
onInvokeTask: (delegate: ZoneDelegate, curr: Zone, target: Zone, task: any, applyThis: any,
applyArgs: any) => {
log.push('invokeTask');
return delegate.invokeTask(target, task, applyThis, applyArgs);
}
});

it('should still in zone after await', function(done) {
async function asyncOutside() {
return 'asyncOutside';
}

const neverResolved = new Promise(() => {});
const waitForNever = new Promise((res, _) => {
res(neverResolved);
});

async function getNever() {
return waitForNever;
};

zone.run(async() => {
const outside = await asyncOutside();
expect(outside).toEqual('asyncOutside');
expect(Zone.current.name).toEqual(zone.name);

async function asyncInside() {
return 'asyncInside';
};

const inside = await asyncInside();
expect(inside).toEqual('asyncInside');
expect(Zone.current.name).toEqual(zone.name);

expect(log).toEqual(['scheduleTask', 'invokeTask', 'scheduleTask', 'invokeTask']);

done();
});
});
});
Loading

0 comments on commit 4b52ea0

Please sign in to comment.