我有一个ProjectClient
类,其中包含用于进行HTTP调用的方法(.GET()
)。它以与node-request相同的方式支持一些参数和回调,但是在幕后也有一些复杂的url和header构建函数:
client.GET(idOrDataObject, function(err, customResponse) {
// url is built based on the id or dataObject passed as the first param
})
成功回复后,返回的对象类型之一是DataObject
:
client.GET(idOrDataObject, function(err, customResponse) {
console.log(customResponse.dataObject instanceof DataObject) // true
})
我正在为名为DataObject
的{{1}}类添加一个便捷方法,该类回调reload()
方法并重新加载,但我希望能够更新{ {1}}使用从服务器返回的新版client.GET()
:
this
用法如下:
DataObject
开始认为这将起作用的唯一方法是,如果我在链中进一步劫持回调,例如在DataObject.prototype.reload = function() {
var args = Array.prototype.slice.call(arguments) // extracts all arguments
var client = helpers.client.validate(args) // ensures 'client' was passed in the args array before continuing
args.unshift(this) // prepends 'this' (the DataObject instance)
// How can I update 'this' with the response contained in the
// callback passed (the last element in 'args')?
return client.GET.apply(client, args)
}
内:
client.GET(idOrDataObject, function(err, customResponse) {
var o = customResponse.dataObject
// assume something changed on the server
o.reload(function(err, done) {
// o has now been updated with the latest copy from the server
})
})
但即使这样做,client.GET
的原始副本也没有被更新 - 就像它被克隆或重复一样,并不是指向原始文件的指针?
这是一项证明失败的测试。如何确保传递到var DataObject = require('../lib/dataObject')
var request = require('request')
var _ = require('lodash')
var GET = function(client, args) {
var options = {
client: client
}
// if a preformatted options argument passed, assign it to options
if (_.isObject(args[0]) && !_.isFunction(args[0]) && args.length <= 2) {
_.assign(options, args[0])
}
options.callback = helpers.cb(_.last(args.filter(_.isFunction)))
options.type = _.first([options.type, args[0]._type, args[0]].filter(_.isString))
options.dataObject = _.first([options.dataObject, args[0]].filter(function(property) {
return (property instanceof DataObject)
}))
request('http://...', {
body: options.body,
json: true,
method: 'GET'
}, function(error, response) {
var customResponse = new CustomResponse(response)
if (options.dataObject instanceof DataObject) {
options.dataObject = customResponse.dataObject
// here I see both 'options.dataObject' and 'customResponse.dataObject' have the correct value for reloadTest
console.log('updated', options.dataObject.reloadTest, customResponse.dataObject.reloadTest)
}
options.callback(error, customResponse, customResponse.dataObject)
})
}
的正确指针?
dataObject
答案 0 :(得分:1)
简短的回答是,你做不到。您实际上无法将对象替换为另一个对象。一些选择:
使用包装器对象,并赋予reload
方法:
client.GET(idOrDataObject, function(err, customResponse) {
var o = new DataWrapper(customResponse);
o.dataObject; // old data
// assume something changed on the server
o.reload(function(err, done) {
o.dataObject; // new data
});
});
更新dataObject
中的数据,保留与以前相同的对象:
DataObject.prototype.reload = function(callback) {
client.GET(this, function(err, customResponse) {
// Assign all properties from the response to the existing obj
// Could also use $.extend, _.extend, etc
Object.assign(this, customResponse.dataObject);
callback(this);
}.bind(this));
}
只需传递回调中的新对象并忽略旧对象:
DataObject.prototype.reload = function(callback) {
client.GET(this, function(err, customResponse) {
callback(customResponse.dataObject);
});
}