Created
May 23, 2017 22:34
-
-
Save lfades/65b1f2bb1d59f720ff794f2d8cc94ebb to your computer and use it in GitHub Desktop.
Comparación entre async/await y promises utilizando un fragmento de codigo de mi implementación con Stripe.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* async/await | |
*/ | |
import request from 'request' | |
import express from 'express' | |
import { GraphQLError } from 'graphql/error' | |
import { STRIPE_API_KEY } from '../configs' | |
const server = express() | |
const TOKEN_URI = 'https://connect.stripe.com/oauth/token' | |
// request.post devuelve su resultado en un callback, aquí se convierte en un promise. | |
// De no hacerlo habría que manejar el callback mas adelante lo cual destruye el flujo. | |
function stripeOAuthToken (code) { | |
return new Promise((resolve, reject) => { | |
request.post({ | |
url: TOKEN_URI, | |
form: { | |
client_secret: STRIPE_API_KEY, | |
grant_type: 'authorization_code', | |
code | |
} | |
}, (error, req, body) => { | |
if (error) { | |
reject(error) | |
} else { | |
resolve(JSON.parse(body)) | |
} | |
}) | |
}) | |
} | |
server.get('/connect/stripe', async (req, res) => { | |
// el codigo de las siguientes definiciones fue acortado por el bien del ejemplo | |
const {query} = req | |
const onError = () => {} | |
const context = {} | |
try { | |
if (!query.code || !query.scope) { | |
throw new GraphQLError('Invalid query') | |
} | |
const {company} = await context.userWithCompany() | |
// Nota: si se consulta de nuevo por el accessToken de Stripe se elimina el token | |
// anterior que fue usado (como si la aplicación nunca se hubiera conectado al usuario) | |
if (company.stripe) { | |
throw new GraphQLError('Already authorized') | |
} | |
const accessToken = await stripeOAuthToken(query.code) | |
if (accessToken.error) { | |
return onError(accessToken) | |
} | |
company.stripe = { | |
userId: accessToken.stripe_user_id, | |
refreshToken: accessToken.refresh_token, | |
scope: accessToken.scope | |
} | |
await company.save() | |
res.redirect('/home') | |
} catch (error) { | |
// estoy utilizando una estructura parecida al error que me trae Stripe | |
// en caso de que nuestro servidor tenga algún error. | |
onError(error) | |
} | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Utilizando las promises como si fueran callbacks, aunque el callback-hell es mucho peor | |
*/ | |
import request from 'request' | |
import express from 'express' | |
import { GraphQLError } from 'graphql/error' | |
import { STRIPE_API_KEY } from '../configs' | |
const server = express() | |
const TOKEN_URI = 'https://connect.stripe.com/oauth/token' | |
// request.post devuelve su resultado en un callback, aquí se convierte en un promise. | |
// De no hacerlo habría que manejar el callback mas adelante lo cual destruye el flujo. | |
function stripeOAuthToken (code) { | |
return new Promise((resolve, reject) => { | |
request.post({ | |
url: TOKEN_URI, | |
form: { | |
client_secret: STRIPE_API_KEY, | |
grant_type: 'authorization_code', | |
code | |
} | |
}, (error, req, body) => { | |
if (error) { | |
reject(error) | |
} else { | |
resolve(JSON.parse(body)) | |
} | |
}) | |
}) | |
} | |
server.get('/connect/stripe', async (req, res) => { | |
// el codigo de las siguientes definiciones fue acortado por el bien del ejemplo | |
const {query} = req | |
const onError = () => {} | |
const context = {} | |
if (!query.code || !query.scope) { | |
// ya no estoy dentro de un try/catch | |
// throw new GraphQLError('Invalid query') | |
return onError('Invalid query') | |
} | |
context.userWithCompany() | |
.then(company => { | |
// Nota: si se consulta de nuevo por el accessToken de Stripe se elimina el token | |
// anterior que fue usado (como si la aplicación nunca se hubiera conectado al usuario) | |
if (company.stripe) { | |
throw new GraphQLError('Already authorized') | |
} | |
stripeOAuthToken(query.code) | |
.then(accessToken => { | |
if (accessToken.error) { | |
onError(accessToken) | |
} else { | |
company.stripe = { | |
userId: accessToken.stripe_user_id, | |
refreshToken: accessToken.refresh_token, | |
scope: accessToken.scope | |
} | |
} | |
company.save() | |
.then(() => { | |
res.redirect('/home') | |
}) | |
.catch(onError) | |
}) | |
.catch(onError) | |
}) | |
.catch(onError) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* promises | |
*/ | |
import request from 'request' | |
import express from 'express' | |
import { GraphQLError } from 'graphql/error' | |
import { STRIPE_API_KEY } from '../configs' | |
const server = express() | |
const TOKEN_URI = 'https://connect.stripe.com/oauth/token' | |
// request.post devuelve su resultado en un callback, aquí se convierte en un promise. | |
// De no hacerlo habría que manejar el callback mas adelante lo cual destruye el flujo. | |
function stripeOAuthToken (code) { | |
return new Promise((resolve, reject) => { | |
request.post({ | |
url: TOKEN_URI, | |
form: { | |
client_secret: STRIPE_API_KEY, | |
grant_type: 'authorization_code', | |
code | |
} | |
}, (error, req, body) => { | |
if (error) { | |
reject(error) | |
} else { | |
resolve(JSON.parse(body)) | |
} | |
}) | |
}) | |
} | |
server.get('/connect/stripe', async (req, res) => { | |
// el codigo de las siguientes definiciones fue acortado por el bien del ejemplo | |
const {query} = req | |
const onError = () => {} | |
const context = {} | |
if (!query.code || !query.scope) { | |
// ya no estoy dentro de un try/catch | |
// throw new GraphQLError('Invalid query') | |
return onError('Invalid query') | |
} | |
let company | |
context.userWithCompany() | |
.then(_company => { | |
// Nota: si se consulta de nuevo por el accessToken de Stripe se elimina el token | |
// anterior que fue usado (como si la aplicación nunca se hubiera conectado al usuario) | |
if (_company.stripe) { | |
throw new GraphQLError('Already authorized') | |
} | |
// si no hago lo siguiente no podre utilizar _company en el siguiente .then | |
company = _company | |
return stripeOAuthToken(query.code) | |
}) | |
.then(accessToken => { | |
if (accessToken.error) { | |
onError(accessToken) | |
} else { | |
company.stripe = { | |
userId: accessToken.stripe_user_id, | |
refreshToken: accessToken.refresh_token, | |
scope: accessToken.scope | |
} | |
} | |
return company.save() | |
}) | |
.then(() => { | |
res.redirect('/home') | |
}) | |
// estoy utilizando una estructura parecida al error que me trae Stripe | |
// en caso de que nuestro servidor tenga algún error. | |
.catch(onError) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment