javascript - redux thunk 不等待任何承诺
Posted
技术标签:
【中文标题】javascript - redux thunk 不等待任何承诺【英文标题】:javascript - redux thunk doesn't wait for any promise 【发布时间】:2017-04-03 00:24:48 【问题描述】:我有一个这样的数组
array =[ message:'http://about.com', message:'http://facebook.com']
我想循环该数组,在每个项目上我都会向服务器发出请求以获取 opengraph 数据,然后将数据保存回数组。这是我所期望的
array =[
message: url:'http://about.com', title:'about'
,
message: url:'http://facebook.com', title:'facebook'
]
然后当一切都结束时。我想用有效载荷调度一个动作是预期的数组。这是我的做法
return dispatch =>
let array =[ message:'http://about.com', message:'http://facebook.com']
let quests = array
.map( (item) =>
axios.get(getOpenGraphOfThisLink + item.message)
.then( result =>
item.message = (result.data)
return result
)
)
Promise.all(quests).then( () =>
console.log( 'modified', array)
dispatch(
type : constant.GET_POST_COLLECTION_SUCCESS,
payload: array
)
// this dispatch function sends my original array instead of modified one.
)
问题:代码中的调度函数会将我的原始数组发送到reducer而不是修改后的数组。我想调度发送新的修改数组。而且我认为应该是,不是吗?
【问题讨论】:
【参考方案1】:现在quests
变量只是由你原来的数组赋值,因为map
函数返回void,但是你需要将每个项目的promise返回给quests
,所以只需添加return
关键字,让你的代码是这样的:
let quests = array
.map( (item) =>
return axios.get(getOpenGraphOfThisLink + item.message)
.then( result =>
item.message = (result.data)
return result
)
)
【讨论】:
直截了当,但请注意我的回答中的附带条件。 我有类似的情况,知道如何解决***.com/questions/40791724/…【参考方案2】:这是一个范围界定问题。您肯定引用了错误的变量:
return dispatch =>
let array =[ // <- the original array
message:'http://about.com'
,
message:'http://facebook.com'
]
let quests = array.map( (item) =>
axios.get(getOpenGraphOfThisLink + item.message)
.then( result =>
item.message = (result.data)
return result
)
)
Promise.all(quests).then(() =>
console.log( 'modified', array) // <- here, array is reference to the original array
dispatch(
type : constant.GET_POST_COLLECTION_SUCCESS,
payload: array
)
// this dispatch function to send my original array instead of modified one.
)
传递给Promise#then
的函数应该接受一个参数,即 Promise 解析的结果。在Promise.all
的情况下,这个单个参数是一个结果数组,每个项目都引用一个具有相应索引的 Promise。所以应该是
return dispatch =>
let array =[
message:'http://about.com'
,
message:'http://facebook.com'
]
let quests = array.map( (item) =>
return axios.get(getOpenGraphOfThisLink + item.message) // don't forget to return when doing Array#map.
.then( result =>
item.message = (result.data)
return result
)
)
Promise.all(quests).then((array) => // <- the new array, redefined in scope of this arrow function
console.log( 'modified', array) // <- here, array is reference to the new array which is the first argument of function passed to Promise#then.
dispatch(
type : constant.GET_POST_COLLECTION_SUCCESS,
payload: array
)
// this dispatch function will send the results of calling all the Promises passed to Promise.all!
)
【讨论】:
返回 axios 工作,但是在 then 函数中添加数组参数将不起作用。所以现在我的代码只需添加'return'关键字就可以了。【参考方案3】:如果我理解正确的话,在使用result.data
完成每个请求后,您正在改变array.message
。
IMO,你不应该这样做
let quests = array.map((item) =>
return axios.get(getOpenGraphOfThisLink + item.message)
.then(result => result.data)
)
Promise.all(quests).then((values) =>
// values contains all the result data.
不要忘记处理错误情况。
【讨论】:
【参考方案4】:允许函数改变传递给它的项目通常不是一个好习惯。
在这种情况下,如果一些 axios.get() 成功而一些失败,您最终会得到一个部分突变的数组,这很可能是不受欢迎的。
相反,您可以映射到原始项目的变异克隆数组,并将映射的数组沿承诺链传递。
假设不涉及“getter”,您可以使用Object.assign()
进行克隆的克隆和变异。
let quests = array.map(item =>
return axios.get(getOpenGraphOfThisLink + item.message)
.then(result => Object.assign(, item, message: result.data );
);
return Promise.all(quests).then(arr =>
console.log('mapped', arr); // note 'mapped', not 'mutated'
// 'x'
dispatch(
'type': constant.GET_POST_COLLECTION_SUCCESS,
'payload': arr
);
);
现在,如果您真的想改变原始数组,您可以在“x”点以全有或全无的方式执行此操作:
Object.assign(array, arr);
【讨论】:
关于这个案例的任何想法***.com/questions/40791724/…以上是关于javascript - redux thunk 不等待任何承诺的主要内容,如果未能解决你的问题,请参考以下文章
javascript 使用Redux-Thunk缓存API响应
javascript 动作创作者。他们将使用thunk进行redux调度
javascript Async Await Action Creator with Redux Thunk
javascript - redux thunk 不等待任何承诺