chore(package): use golike-defer instead of custom implementation

This commit is contained in:
Julien Fontanet 2016-11-30 15:40:30 +01:00
parent 5d0622d2cf
commit 32a371bf13
6 changed files with 7 additions and 221 deletions

View File

@ -58,6 +58,7 @@
"fs-extra": "^1.0.0",
"fs-promise": "^1.0.0",
"get-stream": "^3.0.0",
"golike-defer": "^0.0.0",
"hashy": "~0.5.1",
"helmet": "^3.0.0",
"highland": "^2.5.1",

View File

@ -2,10 +2,7 @@ import bind from 'lodash/bind'
import {
isArray,
isPromise,
isFunction,
noop,
pFinally
isFunction
} from './utils'
// ===================================================================
@ -98,117 +95,6 @@ export const debounce = duration => (target, name, descriptor) => {
// -------------------------------------------------------------------
const _push = Array.prototype.push
export const deferrable = (target, name, descriptor) => {
let fn
function newFn () {
const deferreds = []
const defer = fn => {
deferreds.push(fn)
}
defer.clear = () => {
deferreds.length = 0
}
const args = [ defer ]
_push.apply(args, arguments)
let executeDeferreds = () => {
let i = deferreds.length
while (i) {
deferreds[--i]()
}
}
try {
const result = fn.apply(this, args)
if (isPromise(result)) {
result::pFinally(executeDeferreds)
// Do not execute the deferreds in the finally block.
executeDeferreds = noop
}
return result
} finally {
executeDeferreds()
}
}
if (descriptor) {
fn = descriptor.value
descriptor.value = newFn
return descriptor
}
fn = target
return newFn
}
// Deferred functions are only executed on failures.
//
// i.e.: defer.clear() is automatically called in case of success.
deferrable.onFailure = (target, name, descriptor) => {
let fn
function newFn (defer) {
const result = fn.apply(this, arguments)
return isPromise(result)
? result.then(result => {
defer.clear()
return result
})
: (defer.clear(), result)
}
if (descriptor) {
fn = descriptor.value
descriptor.value = newFn
} else {
fn = target
target = newFn
}
return deferrable(target, name, descriptor)
}
// Deferred functions are only executed on success.
//
// i.e.: defer.clear() is automatically called in case of failure.
deferrable.onSuccess = (target, name, descriptor) => {
let fn
function newFn (defer) {
try {
const result = fn.apply(this, arguments)
return isPromise(result)
? result.then(null, error => {
defer.clear()
throw error
})
: result
} catch (error) {
defer.clear()
throw error
}
}
if (descriptor) {
fn = descriptor.value
descriptor.value = newFn
} else {
fn = target
target = newFn
}
return deferrable(target, name, descriptor)
}
// -------------------------------------------------------------------
const _ownKeys = (
typeof Reflect !== 'undefined' && Reflect.ownKeys ||
(({

View File

@ -4,7 +4,7 @@ import expect from 'must'
// ===================================================================
import {autobind, debounce, deferrable} from './decorators'
import {autobind, debounce} from './decorators'
// ===================================================================
@ -76,98 +76,3 @@ describe('debounce()', () => {
}, 2e1)
})
})
// -------------------------------------------------------------------
describe('deferrable()', () => {
it('works with normal termination', () => {
let i = 0
const fn = deferrable(defer => {
i += 2
defer(() => { i -= 2 })
i *= 2
defer(() => { i /= 2 })
return i
})
expect(fn()).to.equal(4)
expect(i).to.equal(0)
})
it('defer.clear() removes previous deferreds', () => {
let i = 0
const fn = deferrable(defer => {
i += 2
defer(() => { i -= 2 })
defer.clear()
i *= 2
defer(() => { i /= 2 })
return i
})
expect(fn()).to.equal(4)
expect(i).to.equal(2)
})
it('works with exception', () => {
let i = 0
const fn = deferrable(defer => {
i += 2
defer(() => { i -= 2 })
i *= 2
defer(() => { i /= 2 })
throw i
})
expect(() => fn()).to.throw(4)
expect(i).to.equal(0)
})
it('works with promise resolution', async () => {
let i = 0
const fn = deferrable(async defer => {
i += 2
defer(() => { i -= 2 })
i *= 2
defer(() => { i /= 2 })
// Wait a turn of the events loop.
await Promise.resolve()
return i
})
await expect(fn()).to.eventually.equal(4)
expect(i).to.equal(0)
})
it('works with promise rejection', async () => {
let i = 0
const fn = deferrable(async defer => {
// Wait a turn of the events loop.
await Promise.resolve()
i += 2
defer(() => { i -= 2 })
i *= 2
defer(() => { i /= 2 })
// Wait a turn of the events loop.
await Promise.resolve()
throw i
})
await expect(fn()).to.reject.to.equal(4)
expect(i).to.equal(0)
})
})

View File

@ -1,5 +1,6 @@
/* eslint-disable camelcase */
import deferrable from 'golike-defer'
import every from 'lodash/every'
import fatfs from 'fatfs'
import find from 'lodash/find'
@ -20,10 +21,7 @@ import {
import httpRequest from '../http-request'
import fatfsBuffer, { init as fatfsBufferInit } from '../fatfs-buffer'
import {
deferrable,
mixin
} from '../decorators'
import { mixin } from '../decorators'
import {
bufferToStream,
camelToSnakeCase,

View File

@ -1,10 +1,8 @@
import deferrable from 'golike-defer'
import find from 'lodash/find'
import gte from 'lodash/gte'
import lte from 'lodash/lte'
import {
deferrable
} from '../../decorators'
import {
forEach,
mapToArray,

View File

@ -1,3 +1,4 @@
import deferrable from 'golike-defer'
import endsWith from 'lodash/endsWith'
import escapeStringRegexp from 'escape-string-regexp'
import eventToPromise from 'event-to-promise'
@ -15,9 +16,6 @@ import { utcFormat } from 'd3-time-format'
import vhdMerge, { chainVhd } from '../vhd-merge'
import xapiObjectToXo from '../xapi-object-to-xo'
import {
deferrable
} from '../decorators'
import {
forEach,
mapToArray,