在(尝试)切换到 Promise 之前,我可以拥有位于嵌套函数的整个范围内的变量。例如,我可以获得 user
来自数据库,而不是立即使用它,然后在嵌套在链中很远的函数中使用它。
那么,有了 Promise,我必须显式地将所需的变量传递到下一个函数中吗?或者有其他方法可以解决这个问题吗?
目前我的代码看起来像这样
exports.add = function ( req, res ) {
var defer = q.defer()
// check sign in and get user information as 'user'
function getUser ( req, res ) {
User.findOne( { token: req.token }, function ( err, user ) {
if ( err || !user )
return res.json( {
status: "error",
message: "Error authenticating: " + err
})
return user
})
}
... // more functions here
defer.promise
.then( getUser )
.then( youtubeAuthenticate )
.then( getVideoId )
.then( youtubeFind )
.then( makeVideoObject )
defer.resolve( req, res )
}
问题是我无法访问 user
在类似 makeVideoObject
的函数中.
编辑:另一件真正困扰我的事情是我的一些函数如何返回一个值,比如 videoId
这似乎被我的最终函数 makeVideoObject
所识别。 ,但其他的不是,它们之间没有真正的区别。保留在范围内,其他变为 undefined
.
编辑2:我的变量videoId
的原因是“全局”是因为我想我是这样声明的 videoId = ...
。所以这不是 return videoId
这使它成为全局性的,但宣布它的方式。我徒劳地这样做了,
function getUserData () {
user = getUser()
videoId = getVideoId()
youtubeAuthenticate()
}
function getVideoData () {
vData = youtubeFind()
}
defer.promise
.then( getUserData )
.then( getVideoData )
.then( function (user, videoId, vData ) {
makeVideoObject( user, videoId, vData )
})
defer.resolve()
但没有喜悦。一切依旧undefined
.
EDIT3:我已经尝试了下面的回复以及我能想到的任何排列。这是我目前所拥有的。
var user = getUser()
var videoId = getVideoId()
var video = q(videoId).then( youtubeFind )
q.all( [ user, video ] ).then( function( results ) {
if ( !results[0] )
return res.json( "Not authenticated." )
makeVideoObject( results[0], results[1] )
})
使用调试器,两个结果都是未定义的。使用console.log
getUser()
内和youtubeFind()
函数,我看到它们起作用了。这是getUser()
例如,函数。
function getUser () {
User.findOne( { token: req.token }, function ( err, user ) {
return user
})
}
另请注意,我通过添加 authenticateYoutube()
来简化事情直接输入youtubeFind()
.
答案:出于礼貌,我可能会选择下面的答案,但这是对 Node 和 JS 的一系列误解造成了这个问题。这并没有回答所提出的问题,但这就是我做错的事情。
首先,我认为return
,当放入嵌套函数(闭包)时应该是 return <VALUE>
对于它嵌套的“root”函数。实际上,它只是它所在的直接函数的返回值。这里可能是 JS 101。它似乎也不可能影响嵌套函数中父函数中声明的变量。
其次,您需要以某种方式实际构造一个函数,使其像 Promise 一样工作。该格式是这样的:
function getUser () {
var defer = Q.defer() // create the promise object
User.findOne( { token: req.token }, function ( err, user ) {
defer.resolve( user ) // add the return value to the object
})
return defer.promise // return the object, with promise and value
}
最佳答案
如果您想运行多个相互不依赖的任务,然后运行需要这些值的任务,您可以执行以下操作:
Q.all([getUserData(), getVideoData()]).spread(function(user, video) {
// user and video are available
makeVideoObject(user, video)
});
all
接受可以并行获取的 Promise 列表; spread
将这些返回值拆分为单独的参数,然后可以在回调中使用这些参数。这就是你想做的吗?
关于javascript - 我可以在 Node 的 q Promise 中创建全局变量吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28224896/