2015-08-21 63 views
3

下面我创建了一个名为promiseRipple的函数,它接受一个值为函数的对象字面值。每个函数都可以包含同步代码或异步promise保持跟踪变量实例

var _ = require('lodash') 
var Promise = require('bluebird') 

function promiseRipple (start, props) { 
    props = (props) ? props : start 
    start = (props) ? start : {} 
    props = _.mapValues(props, function (prop, key) { 
    prop.key = key 
    return prop 
    }) 
    return Promise.reduce(_.values(props), function (result, action) { 
    if (typeof action !== 'function') throw new Error('property values must be functions') 
    return Promise.resolve(action(start)).then(function (value) { 
     start[action.key] = value 
     return value 
    }) 
    }, null) 
    .then(function() { 
    return start 
    }) 
} 

这里的基本用法

promiseRipple({zero: 'zero'}, { 
    'alpha': function (data) { 
    return Promise.resolve(data.zero + ' alpha') // async -> 'zero alpha' 
    }, 
    'beta': function (data) { 
    return data.zero + ' beta' // -> 'zero beta' 
    }, 
    'gamma': function (data) { 
    return Promise.resolve(data.zero + ' gamma') // async -> 'zero gamma' 
    }, 
    'delta': function (data) { 
    return Promise.resolve(data.zero + data.alpha + ' delta') // async -> 'zerozero alpha delta' 
    }, 
}).then(function (results){ 
    // results -> { 
    // zero: 'zero', 
    // alpha: 'zero alpha', 
    // beta: 'zero beta', 
    // gamma: 'zero gamma', 
    // delta: 'zerozero alpha delta' 
    // } 
}) 

我想在一些functionalty添加要提出的是所以每当data是一个函数内返回,新的数据化子性质将扩大到现有的。

promiseRipple({zero: 'zero'}, { 
    'alpha': function (data) { 
    return Promise.resolve(data.zero + ' alpha') // async -> 'zero alpha' 
    }, 
    'beta': function (data) { 
    data.foo = data.zero + ' foo' // -> 'zero foo' 
    data.bar = data.zero + ' bar' // -> 'zero bar' 
    return data 
    }, 
    'gamma': function (data) { 
    return Promise.resolve(data.zero + ' gamma') // async -> 'zero gamma' 
    }, 
    'delta': function (data) { 
    return Promise.resolve(data.zero + data.alpha + ' delta') // async -> 'zerozero alpha delta' 
    }, 
}).then(function (results){ 
    // results -> { 
    // zero: 'zero', 
    // alpha: 'zero alpha', 
    // foo: 'zero foo', 
    // bar: 'zero bar', 
    // gamma: 'zero gamma', 
    // delta: 'zerozero alpha delta' 
    // } 
}) 

我试图使自定义对象的文字,将允许我以检测是否从道具函数返回值为data或者一些新的变量。但是这不起作用。

var _ = require('lodash') 
var Promise = require('bluebird') 

function Start (data) { 
    if (data) return data 
    return {} 
} 
Start.prototype = Object.prototype 

function promiseRipple (start, props) { 
    props = (props) ? props : start 
    start = (props) ? new Start(start) : new Start() 
    props = _.mapValues(props, function (prop, key) { 
    prop.key = key 
    return prop 
    }) 
    return Promise.reduce(_.values(props), function (result, action) { 
    if (typeof action !== 'function') throw new Error('property values must be functions') 
    return Promise.resolve(action(start)).then(function (value) { 
     console.log(value instanceof Start) 
     if (value instanceof Start) { 
     _.extend(start, value) 
     return start 
     } else { 
     start[action.key] = value 
     return value 
     } 
    }) 
    }, null) 
    .then(function() { 
    return start 
    }) 
} 

module.exports = promiseRipple 

什么是检测返回的对象是否与我们开始使用的同一对象而不干扰对象值的好方法?

+0

没有什么是异步的。这仅仅是为了演示目的吗?如果不是,取消所有承诺会使一切变得更简单。 – Amit

+0

问题没有意义。关于数据和承诺的所有细节都与实际提出的问题无关。如果你不信任一个函数不要混淆对象,那么不要传递它。改为传递(深)克隆。 –

+0

不要这样做。对象本质上是无序的。你不能依赖任何特定的函数应该执行的顺序。 – Bergi

回答

1

由于它与您的问题的动机有关,所以您应该注意,在JavaScript中,非原始变量被“通过引用”传递给函数。这意味着当函数被引用到函数之外时,函数中对象的更改将反映到对象中,并且它是否传递回来并不重要。

要回答你的问题,你可以检查对象和返回值之间的相等性。

注意:这里

function f(obj) { 
    obj.b = 'b test'; 
    return obj; 
} 

var obj_1 = {}; 
obj_1.a = 'a test'; 
// This is really just a reference to the same object as obj_1 
var obj_2 = f(obj_1); 

console.log(obj_1); // {a: "a test", b: "b test"} 
console.log(obj_2); // {a: "a test", b: "b test"} 
// Here is how you can test for equality with the original object passed in 
console.log(obj_1 === obj_2); // true 
+0

这真是太棒了,是的,它是相同的对象变量,所以我可以检查'开始===值'并且只需返回'value'没有'clone'就够了。这真是太神奇了,我已经超越了它。 – ThomasReggi

+0

乐意帮忙!如果这回答你的问题,一定要标记它。 :) –