【发布时间】:2017-11-29 23:00:37
【问题描述】:
我的代码试图做的是创建一个具有一些动态属性的对象数组,这些属性将作为某些函数的结果来填充。我正在尝试使用 Promise,否则我的模板会在函数完成之前呈现,并且这些对象的属性将为 null 或未定义,从而导致模板出错。
这是第一个函数
fetchUserPortfolioCoins({ commit, dispatch, state, rootGetters }) {
const promises = []
promises.push(dispatch('utilities/setLoading', true, { root: true })) // start loader
if (!rootGetters['auth/isAuthenticated']) {
// if user isn't logged, pass whatever is in the store, so apiDetails will be added to each coin
let coins = state.userPortfolioCoins
coins.forEach(coin => { promises.push(dispatch('createAcqCostConverted', coin)) })
commit('SET_USER_COINS', { coins, list: 'userPortfolioCoins' })
} else {
// otherwise, pass the response from a call to the DB coins
Vue.axios.get('/api/coins/').then(response => {
let coins = response.data
coins.forEach(coin => { promises.push(dispatch('createAcqCostConverted', coin)) })
commit('SET_USER_COINS', { coins, list: 'userPortfolioCoins' })
})
}
Promise.all(promises)
.then(() => {
commit('SET_USER_PORTFOLIO_OVERVIEW')
dispatch('utilities/setLoading', false, { root: true })
})
.catch(err => { console.log(err) })
},
那叫这个:
createAcqCostConverted({ dispatch, rootState }, coin) {
const promises = []
// this check is only going to happen for sold coins, we are adding sell_price_converted in case user sold in BTC or ETH
if (coin.sell_currency === 'BTC' || coin.sell_currency === 'ETH') {
const URL = `https://min-api.cryptocompare.com/data/pricehistorical?fsym=${coin.coin_symbol}&tsyms=${rootState.fiatCurrencies.selectedFiatCurrencyCode}&ts=${coin.sold_on_ts}`
promises.push(Vue.axios.get(URL, {
transformRequest: [(data, headers) => {
delete headers.common.Authorization
return data
}]
}))
}
// if user bought with BTC or ETH we convert the acquisition cost to the currently select fiat currency, using the timestamp
if (coin.buy_currency === 'BTC' || coin.buy_currency === 'ETH') {
const URL = `https://min-api.cryptocompare.com/data/pricehistorical?fsym=${coin.coin_symbol}&tsyms=${rootState.fiatCurrencies.selectedFiatCurrencyCode}&ts=${coin.bought_on_ts}`
promises.push(Vue.axios.get(URL, {
transformRequest: [(data, headers) => {
delete headers.common.Authorization
return data
}]
}))
} else {
// if the selected fiatCurrency is the same as the buy_currency we skip the conversion
if (coin.buy_currency === rootState.fiatCurrencies.selectedFiatCurrencyCode) {
coin.acquisition_cost_converted = NaN
return coin
// otherwise we create the acq cost converted property
} else promises.push(dispatch('fiatCurrencies/convertToFiatCurrency', coin, { root: true }))
}
Promise.all(promises)
.then(response => {
const value = response[0].data[coin.coin_symbol][rootState.fiatCurrencies.selectedFiatCurrencyCode]
if (coin.sell_currency === 'BTC' || coin.sell_currency === 'ETH') coin.acquisition_cost_converted = value
if (coin.buy_currency === 'BTC' || coin.buy_currency === 'ETH') coin.acquisition_cost_converted = value
return coin
})
.catch(err => { console.log(err) })
},
问题是第一个函数没有等待第二个函数完成。如何调整此代码以解决此问题?
谢谢
【问题讨论】:
-
尝试将您的示例缩减为一个仍然显示问题的最小独立示例。如果你很幸运,这样做就足以让你自己弄清楚问题所在。如果没有,其他人会更容易看到并帮助您。另请参阅sscce.org,了解有关如何减少和生成良好示例的更多提示。
-
createAcqCostConverted有时会返回coin(即if the selected fiatCurrency is the same as the buy_currency- 在这种情况下,任何被推送到承诺的 Promise 都将“丢失”)并且在其他时候返回undefined...并且永远不会返回一个 Promise - 最后的 Promise.all 语句不会“神奇地”返回一个 Promise,如果你想返回一个 Promise,你需要return Promise.all -
@JaromandaX 谢谢,我很困惑将返回值放在哪里,如果在 .then() 内或在哪里,这消除了一些混乱.. 仍然第一个函数不能作为预计
-
是的,在 .then 内也是如此 - 如果第二个函数没有返回你期望它返回承诺的承诺,那么第一个函数(即期望来自第二个函数的承诺或值)不会工作
标签: javascript vue.js promise vuejs2 vuex