我在node.js中使用ES6。长话短说,我现在才谈到回调,并想用Promise代替它们。
我进行了一个测试项目,以从api /端点获取oauth2令牌,对其进行刷新并最终将其撤销。目标是将上一个请求的响应传递给下一个。我的代码如下:
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''未定义'收到。另外我也不知道这是否有帮助,但这是“ 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
答案 0 :(得分:1)
通过在then
块末尾返回另一个Promise来链接Promise。您似乎在第一个return
块中没有正确调用then
。您应按以下步骤进行更正:
oauth2Adapter.RequestNewAccessToken()
.then(function (requestReponse) {
console.log(response)
return oauth2Adapter.RefreshAccessToken()
})
.then(function (refreshResponse) {
return oauth2Adapter.RevokeAccessToken(JSON.parse(refreshResponse.body))
})
作为一个旁注,我希望在每次Promise返回中为回调args取不同的名称,这将有助于保持环境清洁!
答案 1 :(得分:0)
承诺应正确地链接。这意味着then
和catch
回调应返回承诺链,以防万一。
此外,使用response
时,json: true
参数是解析的响应正文。如果服务器以令牌对象作为响应,则应将其作为参数传递给期望它的函数:
...
.then(function (response) {
console.log(response)
return oauth2Adapter.RefreshAccessToken(response)
})
...
答案 2 :(得分:0)
Your second code block is not using promises at all well
try the following instead
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 }
As for your code that USES this - you console.log(response)
which has the required format, but then you oauth2Adapter.RefreshAccessToken(response.body)
... response has no body!
So, simply do:
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()
but, since you pass response
straight to the next function without any processing, you can also do
const oauth2Adapter = require('./api/adapter/oauth2Adapter')
function test () {
return oauth2Adapter.RequestNewAccessToken()
.then(oauth2Adapter.RefreshAccessToken)
.then(oauth2Adapter.RevokeAccessToken)
.then(console.log)
.catch(console.log)
}
test()