Meteor 方法调用 returns 在客户端未定义但在服务器上未定义
Meteor method call returns undefined on the client but not on the server
更新
我刚刚意识到这种方法存在根本性的错误,嵌套回调不能 return 对其父回调有影响。我进入 JS 世界的时间较晚,来自 Promises
时代,不知道这是回调的问题。但是我没有看到足够多的 Meteor 使用 promises 的例子,所以我改用回调。但是,如果可以改进此代码,我将不胜感激。
问题
所以我使用以下方法从客户端调用一个方法:
Meteor.call('cart.useProfileAddress', {}, (error, address) => {
console.info('Address', address) // this returns undefined on client
})
这是我api/carts/cartsMethod.js
中的方法
export const useProfileAddress = new ValidatedMethod({
name: 'cart.useProfileAddress',
validate(args) {
//
},
run(args) {
const person = Persons.findOne({'userId': Meteor.userId()});
// If I do the return here I get the address in the browser as defined.
// return person.address
// I'm calling another method under here:
getClosestStore.call({address: person.address}, (error, result) => {
// And another one method call here:
updateCartAddress.call({address: person.address}, (error, result) => {
// So once all the callbacks are done return the address here.
// However the problem is I get `undefined` on the client.
if (!error) {
// console displays something on the Server but is `undefined` on the Client
console.info('Returning Address', person.address)
return person.address
}
})
})
}
})
上面的代码可能有什么问题?会不会是因为我试图从嵌套回调中获取值?
还有谁知道如何避免这些嵌套回调?我知道如何使用 promises 在 Node
上做到这一点,但在 Meteor 中(我正在使用 1.4
)我仍然一无所知。
方法可以 运行 在服务器上同步,因此您不需要使用回调。方法执行后会返回结果,如果出错会抛出异常。试试这个:
export const useProfileAddress = new ValidatedMethod({
// ...
run(args) {
const person = Persons.findOne({'userId': Meteor.userId()});
const result1 = getClosestStore.call({address: person.address});
// use result1 if you need to
const result2 = updateCartAddress.call({address: person.address});
// // use result2 if you need to
return person.address;
}
})
这就是我使用 Promise 和 Meteor 的新 async/await
功能解决问题的方法 1.3+
export const useProfileAddress = new ValidatedMethod({
name: 'cart.useProfileAddress',
validate(args) {
//
},
run(args) {
return ((async () => {
const person = Persons.findOne({'userId': Meteor.userId()});
const storeId = await getClosestStore.callPromise({address: person.address})
const newAddress = await updateCartAddress.callPromise({address: person.address})
return newAddress
})())
}
})
在每个方法中我都使用了 didericis:callpromise-mixin 这样它就会 return 一个 promise。
更新
我刚刚意识到这种方法存在根本性的错误,嵌套回调不能 return 对其父回调有影响。我进入 JS 世界的时间较晚,来自 Promises
时代,不知道这是回调的问题。但是我没有看到足够多的 Meteor 使用 promises 的例子,所以我改用回调。但是,如果可以改进此代码,我将不胜感激。
问题
所以我使用以下方法从客户端调用一个方法:
Meteor.call('cart.useProfileAddress', {}, (error, address) => {
console.info('Address', address) // this returns undefined on client
})
这是我api/carts/cartsMethod.js
export const useProfileAddress = new ValidatedMethod({
name: 'cart.useProfileAddress',
validate(args) {
//
},
run(args) {
const person = Persons.findOne({'userId': Meteor.userId()});
// If I do the return here I get the address in the browser as defined.
// return person.address
// I'm calling another method under here:
getClosestStore.call({address: person.address}, (error, result) => {
// And another one method call here:
updateCartAddress.call({address: person.address}, (error, result) => {
// So once all the callbacks are done return the address here.
// However the problem is I get `undefined` on the client.
if (!error) {
// console displays something on the Server but is `undefined` on the Client
console.info('Returning Address', person.address)
return person.address
}
})
})
}
})
上面的代码可能有什么问题?会不会是因为我试图从嵌套回调中获取值?
还有谁知道如何避免这些嵌套回调?我知道如何使用 promises 在 Node
上做到这一点,但在 Meteor 中(我正在使用 1.4
)我仍然一无所知。
方法可以 运行 在服务器上同步,因此您不需要使用回调。方法执行后会返回结果,如果出错会抛出异常。试试这个:
export const useProfileAddress = new ValidatedMethod({
// ...
run(args) {
const person = Persons.findOne({'userId': Meteor.userId()});
const result1 = getClosestStore.call({address: person.address});
// use result1 if you need to
const result2 = updateCartAddress.call({address: person.address});
// // use result2 if you need to
return person.address;
}
})
这就是我使用 Promise 和 Meteor 的新 async/await
功能解决问题的方法 1.3+
export const useProfileAddress = new ValidatedMethod({
name: 'cart.useProfileAddress',
validate(args) {
//
},
run(args) {
return ((async () => {
const person = Persons.findOne({'userId': Meteor.userId()});
const storeId = await getClosestStore.callPromise({address: person.address})
const newAddress = await updateCartAddress.callPromise({address: person.address})
return newAddress
})())
}
})
在每个方法中我都使用了 didericis:callpromise-mixin 这样它就会 return 一个 promise。