Javascript Promises嵌套深度就像回调
我正在尝试使用Promises和异步函数。 根据我的理解,诺言应该可以缓解回拨地狱。 不过看起来我的代码还是非常深的嵌套。
我是否错过了一些有关承诺的内容(可以将其重写为更具可读性/惯用性),或者有时会像回调一样做承诺嵌套?
在这个例子中,我构建了一个调用API从一些社交媒体帐户中检索朋友列表的函数。 如果由于认证错误导致初始呼叫失败,我知道我必须先认证并再次进行呼叫。
const myRequest = { /* custom instance of 'request-promise' */ }
function getFriendsList() {
return new Promise((resolve, reject) => {
myRequest.get('/getFriendList').then(resp => {
if (needsAuthentication(resp)) {
myRequest.post('/auth', credentials).then(() => {
myRequest.get('/getFriendList').then(resp => resolve(resp.body))
}).catch(err => {
reject(err)
})
} else {
resolve(resp.body)
}
}).catch(err => {
reject(err)
})
})
}
function authenticate() {
return new Promise((resolve, reject) => {
getCredentials().then(credentials => {
myRequest.post('/auth').then(resp => {
return resp.statusCode == '200' ? resolve(resp) : reject(resp)
})
}).catch(err => reject(err))
})
}
如果一个Promise用Promise解决,它本身不解决,而是等待传递的Promise解决。 所以Promise链条变平了。 同样适用于从then
链中返回Promise。 这非常有用:
function getFriendsList() {
return myRequest.get('/getFriendList').then(resp => {
if (needsAuthentication(resp)) {
return myRequest.post('/auth', credentials).then(() =>
myRequest.get('/getFriendList').then(resp => resp.body)
);
} else {
return resp.body;
}
});
}
function authenticate() {
return getCredentials()
.then(credentials => myRequest.post('/auth'))
.then(resp => {
if(resp.statusCode == '200'){
return resp;
} else {
throw resp;
}
})
}
阻止
回调地狱
我们有Promise
方式,但现在要防止
诺言地狱
我们有async/await
语法
你的代码应该是这样的
async function getFriendsList() {
var resp = await myRequest.get('/getFriendList')
if (needsAuthentication(resp)) {
await myRequest.post('/auth', credentials)
var resp2 = await myRequest.get('/getFriendList')
return resp2.body
} else {
return resp.body
}
}
async function authenticate() {
var credentials = await getCredentials()
var resp = await myRequest.post('/auth')
return resp
}
永远记住任何Promise.reject()
或异步函数中的任何throw Error
都会导致被拒绝的函数(Promise)。
所以,在你的authenticate
功能
async function authenticate() {
var credentials = await getCredentials()
var resp = await myRequest.post('/auth') //If this get rejected
return resp
}
authenticate().then().catch(error => console.log('error here', error))
总记得
async
函数只是Promises
,在代码中拒绝或抛出Error
时, return
并reject
它
上一篇: Javascript Promises nest deeply just like callbacks
下一篇: Promise waterfall