2015-08-21 101 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

樂意幫忙!如果這回答你的問題,一定要標記它。 :) –