javascript - 我可以在 Node 的 q Promise 中创建全局变量吗?

标签 javascript node.js promise

在(尝试)切换到 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/

相关文章:

javascript - 使用 Javascript 按索引获取 HTML 有序列表中的元素

node.js - Express 和 MEAN 堆栈中的路由

javascript - 从另一个 promise 返回 promise 的原因?

javascript - 在 AngularJS 中的已解决的 Promise 上使用 ng-model (奇怪的行为)

javascript - 如果并行函数已经失败,则阻止函数运行(使用 jQuery $.when())

javascript - 来自 javascript 的同步 Json 调用

javascript - 根据所选语言渲染模型中的标签

node.js - 我的Node.js Web服务上的回调 hell 发送到elasticsearch

javascript - 使用 Rollup 解决 woff 导入问题

javascript - 如何将嵌套的 setTimeouts 转换为 promises