Цепочка обещаний, используйте результат запроса для другого - PullRequest
0 голосов
/ 02 октября 2018

Я использую ES6 в node.js.Короче говоря, я только сейчас о обратных вызовах и хочу заменить их обещаниями.

Я сделал тестовый проект, чтобы получить токен oauth2 из конечной точки api /, обновить его и, наконец, отозвать.Цель состоит в том, чтобы дать ответ от предыдущего запроса к следующему.Мой код выглядит так:

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()

Первое обещание возвращает ответ.Следующим шагом теперь является передача второго обещания в качестве параметра.Но второе обещание получает только неопределенный объект.

Я ученик второго года обучения в 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

Ответы [ 3 ]

0 голосов
/ 02 октября 2018

Обещания должны быть правильно прикованы .Это означает, что обратные вызовы then и catch должны возвращать обещание для цепочки, если оно есть.

Кроме того, параметр response является анализируемым телом ответа, когда используется json: true.Если сервер отвечает маркерным объектом, его следует передать в качестве аргумента ожидающей его функции:

...
.then(function (response) {
  console.log(response)
  return oauth2Adapter.RefreshAccessToken(response)
})
...
0 голосов
/ 02 октября 2018

Ваш второй блок кода вообще не использует обещания

вместо этого попробуйте следующее

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.log(response), который имеет требуемый формат, но тогда вы oauth2Adapter.RefreshAccessToken(response.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()

но, поскольку вы передаете response прямо в следующую функцию без каких-либообработку, вы также можете сделать

const oauth2Adapter = require('./api/adapter/oauth2Adapter')
function test () {
    return oauth2Adapter.RequestNewAccessToken()
    .then(oauth2Adapter.RefreshAccessToken)
    .then(oauth2Adapter.RevokeAccessToken)
    .then(console.log)
    .catch(console.log)
}
test()
0 голосов
/ 02 октября 2018

Обещания объединяются в цепочку, возвращая еще одно Обещание в конце блока then.Похоже, вы не правильно вызвали return в первом блоке then.Вы должны исправить это следующим образом:

oauth2Adapter.RequestNewAccessToken()
.then(function (requestReponse) {
  console.log(response)
  return oauth2Adapter.RefreshAccessToken()
})
.then(function (refreshResponse) {
  return oauth2Adapter.RevokeAccessToken(JSON.parse(refreshResponse.body))
})

Как sidenote, я люблю называть мои аргументы обратного вызова по-разному при каждом возврате Promise, что поможет содержать вещи в чистоте!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...