Javascript 承诺链接,使用另一个请求的结果
我在node.js中使用ES6。长话短说,我现在才开始谈论回调,并希望用承诺来取代它们 我做了一个测试项目,从api/端点获取oauth2令牌,刷新它并最终撤销它。目标是将上一个请求的响应传递给下一个请求。我的代码如下所示:Javascript 承诺链接,使用另一个请求的结果,javascript,node.js,es6-promise,Javascript,Node.js,Es6 Promise,我在node.js中使用ES6。长话短说,我现在才开始谈论回调,并希望用承诺来取代它们 我做了一个测试项目,从api/端点获取oauth2令牌,刷新它并最终撤销它。目标是将上一个请求的响应传递给下一个请求。我的代码如下所示: const oauth2Adapter = require('./api/adapter/oauth2Adapter') function test () { oauth2Adapter.RequestNewAccessToken() .then(function (re
const oauth2Adapter = require('./api/adapter/oauth2Adapter')
function test () {
oauth2Adapter.RequestNewAccessToken()
.then(function (response) {
console.log(response)
return oauth2Adapter.RefreshAccessToken(response.body)
})
.then(function (response) {
return oauth2Adapter.RevokeAccessToken(response.body)
})
.then(console.log)
.catch(console.log)
}
test()
第一个承诺返回它的响应。下一步是将它作为参数赋给第二个promise。但是第二个承诺只接收一个未定义的对象
我是一名二年级的cs学徒,任何评论家都会帮助我,并对我表示感谢
编辑:添加“return”关键字不会改变这种情况。问题是“RefreshAccessToken”“undefined”接收的是。我也不知道这是否有帮助,但下面是“oauth2Adapter.js”代码:
const Promise = require('promise')
const rp = require('request-promise')
const credentials = require('../../misc/credentials/Staging')
function RequestNewAccessToken () {
try {
const response = rp({
method: 'POST',
url: `${credentials.baseUrl}/oauth/token`,
form: {
client_id: credentials.apiKey,
client_secret: credentials.apiSecret,
username: credentials.username,
password: credentials.password,
grant_type: credentials.grantType
},
json: true
})
return Promise.resolve(response)
} catch (error) {
return Promise.reject(error)
}
}
function RefreshAccessToken (token) {
try {
const response = rp({
method: 'POST',
url: `${credentials.baseUrl}/oauth/token`,
form: {
client_id: credentials.apiKey,
client_secret: credentials.apiSecret,
grant_type: 'refresh_token',
refresh_token: token.refresh_token
},
json: true
})
return Promise.resolve(response)
} catch (error) {
return Promise.reject(error)
}
}
function RevokeAccessToken (token) {
try {
const response = rp({
method: 'POST',
url: `${credentials.baseUrl}/oauth/revoke`,
form: {
client_id: credentials.apiKey,
client_secret: credentials.apiSecret,
token: token.access_token
},
json: true
})
return Promise.resolve(response)
} catch (error) {
return Promise.reject(error)
}
}
module.exports = { RequestNewAccessToken, RefreshAccessToken, RevokeAccessToken }
如果我执行代码,我将通过stdout获得以下文本:
Debugger attached.
{ access_token: '31744bf03a2fb92edb67fcbeead14f4ed8c540843c2439179a54b6439dc94c0e',
token_type: 'Bearer',
expires_in: 660,
refresh_token: 'e53642c69bd0ad954d886dad7a437f88c8c269ecacf2cdcfebc8af1a2d0d9b1e',
created_at: 1538471914 }
TypeError: Cannot read property 'refresh_token' of undefined
at Object.RefreshAccessToken (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/api/adapter/oauth2Adapter.js:28:28)
at /Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/Main.js:7:28
at tryCatcher (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/util.js:16:23)
at Promise._settlePromiseFromHandler (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/promise.js:512:31)
at Promise._settlePromise (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/promise.js:569:18)
at Promise._settlePromise0 (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/promise.js:614:10)
at Promise._settlePromises (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/promise.js:694:18)
at _drainQueueStep (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/async.js:138:12)
at _drainQueue (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/async.js:131:9)
at Async._drainQueues (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/async.js:147:5)
at Immediate.Async.drainQueues (/Users/quest1onmark/coding_stuff/nodejs/EdgeDeviceAdministration/node_modules/bluebird/js/release/async.js:17:14)
at runCallback (timers.js:810:20)
at tryOnImmediate (timers.js:768:5)
at processImmediate [as _immediateCallback] (timers.js:745:5)
Waiting for the debugger to disconnect...
Process finished with exit code 0
承诺通过在then块末尾返回另一个承诺来链接。看起来您在第一个then块中没有正确调用return。您应按以下方式更正此问题:
oauth2Adapter.RequestNewAccessToken()
.then(function (requestReponse) {
console.log(response)
return oauth2Adapter.RefreshAccessToken()
})
.then(function (refreshResponse) {
return oauth2Adapter.RevokeAccessToken(JSON.parse(refreshResponse.body))
})
作为旁注,我喜欢在每次承诺返回时对回调参数进行不同的命名,这将有助于保持事情的整洁 承诺应该被正确地链接起来。这意味着then和catch回调应该向chain返回一个承诺,以防有承诺 此外,当使用json:true时,响应参数将被解析为响应体。如果服务器使用令牌对象进行响应,则应将其作为参数传递给期望它的函数:
...
.then(function (response) {
console.log(response)
return oauth2Adapter.RefreshAccessToken(response)
})
...
您的第二个代码块根本没有很好地使用承诺 请尝试以下方法
const Promise = require('promise')
const rp = require('request-promise')
const credentials = require('../../misc/credentials/Staging')
function RequestNewAccessToken () {
return rp({
method: 'POST',
url: `${credentials.baseUrl}/oauth/token`,
form: {
client_id: credentials.apiKey,
client_secret: credentials.apiSecret,
username: credentials.username,
password: credentials.password,
grant_type: credentials.grantType
},
json: true
});
}
function RefreshAccessToken (token) {
return rp({
method: 'POST',
url: `${credentials.baseUrl}/oauth/token`,
form: {
client_id: credentials.apiKey,
client_secret: credentials.apiSecret,
grant_type: 'refresh_token',
refresh_token: token.refresh_token
},
json: true
});
}
function RevokeAccessToken (token) {
return rp({
method: 'POST',
url: `${credentials.baseUrl}/oauth/revoke`,
form: {
client_id: credentials.apiKey,
client_secret: credentials.apiSecret,
token: token.access_token
},
json: true
});
}
module.exports = { RequestNewAccessToken, RefreshAccessToken, RevokeAccessToken }
对于使用此选项的代码,您可以使用console.logresponse,它具有所需的格式,但是您可以使用oauth2Adapter.RefreshAccessTokenresponse.body。。。回应没有身体
因此,只要做:
const oauth2Adapter = require('./api/adapter/oauth2Adapter')
function test () {
return oauth2Adapter.RequestNewAccessToken()
.then(response => oauth2Adapter.RefreshAccessToken(response))
.then(response => oauth2Adapter.RevokeAccessToken(response))
.then(console.log)
.catch(console.log)
}
test()
但是,由于直接将响应传递给下一个函数而不进行任何处理,所以也可以这样做
const oauth2Adapter = require('./api/adapter/oauth2Adapter')
function test () {
return oauth2Adapter.RequestNewAccessToken()
.then(oauth2Adapter.RefreshAccessToken)
.then(oauth2Adapter.RevokeAccessToken)
.then(console.log)
.catch(console.log)
}
test()
就我现在和其他用户所报告的情况而言,我已经完全阅读了可能的副本,但它没有描述我的问题,因为我正确地使用了承诺。我已经在应该的位置添加了“return”关键字,但没有任何更改。你能看看我做的编辑,告诉我是否理解错了什么吗?这对我有很大帮助。我已经在应该的位置添加了“return”关键字,但没有任何改变。你能看看我做的编辑,告诉我是否理解错了什么吗?这会帮我很大的忙。您仍然错过了oauth2Adapter.RefreshAccessToken的返回@JonasRaphaelSchultheiss@JonasRaphaelSchultheiss我看不出有什么问题,除了你使用try..catch,Promise.resolve和Promise.reject这些不需要的东西,它们不应该引起问题。它可能只是返回rp。。。。修复代码似乎不太可能暴露与错误相同的行为。我建议您再次检查您是否正在运行已修复的代码。我非常确定我执行的代码是正确的。我会做一个快速重启,即使我不希望它工作后,它的想法是重要的。我在问题中添加了错误消息,但我认为这没有帮助。谢谢你的帮助。@Jonasrafaelschultheis我明白了。我误解了“RefreshAccessToken”“undefined”接收可能意味着什么。您没有将参数传递给RefreshAccessToken,而它需要一个令牌。顺便说一句,使用JSON:true时不需要JSON.parse。它不是一个就是另一个。RefreshAccesToken仍接收“未定义”。我已经添加了错误消息。谢谢您的帮助。当然可以-我没有修复的代码调用返回oauth2Adapter.RefreshAccessToken。。。没有争论。。。该怎么办;参数be?是一个输入错误,在我的代码中,它看起来像是返回oauth2Adapter.RefreshAccessTokenresponse.bodyOK,那么你是说你仍然没有定义?即使是在通过response.body时?这意味着response.body未定义。。。这不是我能解决的问题,因为我不知道你在请求中得到了什么。我已经在第三个代码块中展示了我得到的。就在错误消息的上方。我真的不明白我做错了什么,我觉得我在浪费你和别人的时间。