redux thunk - 承诺完成后如何在嵌套数组中调度数据 [英] redux thunk - how dispatch data in nested array after promise finish

查看:44
本文介绍了redux thunk - 承诺完成后如何在嵌套数组中调度数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将 newArray 中的所有默认文本"转换为新文本".然后用新文本"发送数组.问题是调度函数正在调度默认文本".看起来它不等待承诺.下面代码中我的 Promise 设置有什么问题?

返回调度=>{让新数组 =[{ post:[ {message:'default text'}, {message:'default text'}] }]让任务 = newarray.map( (i) => {返回 i.post.map( (item) => {返回 axios.get(someLink).then( result =>{item.message = '新文本'返回结果})})})Promise.all(quests).then(() => {派遣({类型:constant.GET_SUCCESS,有效载荷:newarray})}).catch(() =>{console.log('没有结果')})}

解决方案

你的输入数据结构是这样的:

<预><代码>[{邮政: [{消息:'默认文本'},{消息:'默认文本'}]}]

您的代码将其转换为:

<预><代码>[[承诺<Axios>,承诺<Axios>]]

所以在外层没有办法知道内层承诺何时完成.我们需要额外的承诺层来将这些信息向上移动到对象图中.本质上,我们需要:

承诺<[承诺<[承诺<Axios>,承诺<Axios>]>]>

所以当所有内部承诺都这样做时,顶级承诺可以解决.执行此操作的代码看起来非常相似:

返回函数(){var newarray = [{ post: [{ message: 'default text' }, { message: 'default text' }] }];返回 Promise.all(newarray.map(function (i) {返回 Promise.all(i.post.map(function (item) {返回 axios.get(someLink).then(function (result) {item.message = '新文本';});}));})).then(函数(){返回 {类型:constant.GET_SUCCESS,有效载荷:newarray};}).catch(函数(错误){返回 {类型:constant.GET_ERROR,有效载荷:无结果"+ 错误};});};

如果您认为可以提高清晰度,可以使用箭头函数(我不认为):

return () =>{var newarray = [{ post: [{ message: 'default text' }, { message: 'default text' }] }];返回 Promise.all(newarray.map( i => Promise.all(i.post.map( item => axios.get(someLink).then( result => {item.message = '新文本';}) )))).then( () => ({类型:constant.GET_SUCCESS,有效载荷:newarray})).catch( (错​​误) => ({类型:constant.GET_ERROR,有效载荷:无结果"+ 错误}));};

<小时>

一般备注:我已从您的代码中删除了回调函数.它与 promise 背后的哲学相矛盾,即从它们内部调用代码继续回调.

而不是这样做(本质上是您的代码):

function bla(callback) {asyncFunction().then(someProcessing).then(callback);}

这样做:

function blaAsync() {返回 asyncFunction().then(someProcessing);}

注意第二个变体如何不再依赖于它的调用者.它只是执行其任务并返回结果.调用者可以决定如何处理它:

blaAsync().then(function (result) {//回调"会做什么})

I want to turn all 'default text' in newArray to 'new text'. Then dispatch the array with 'new text'. The problem is dispatch function is dispatching the 'default text'. Look like it does not wait for promise. What's wrong with my promise setup in the code below?

return dispatch => {
    let newarray =[ 
        { post:[ {message:'default text'}, {message:'default text'}] }
    ]
    let quests = newarray.map( (i) => {
        return i.post.map( (item) => {
            return axios.get(someLink).then( result =>{
                item.message = 'new text'
                return result
            })
        })
    })

    Promise.all(quests).then( () => {
        dispatch({
            type: constant.GET_SUCCESS,
            payload: newarray
        })
    }).catch( () =>{
        console.log('no result')
    })
}

解决方案

Your input data structure is like this:

[
    {
        post: [
            {message:'default text'},
            {message:'default text'}
        ]
    }
]

Your code transforms it into this:

[
    [
        Promise<Axios>,
        Promise<Axios>
    ]
]

So at the outer level there is no way of knowing when the inner promises have finished. We need extra layers of promises to move that information up the object graph. Essentially, we need:

Promise<[
    Promise<[
        Promise<Axios>,
        Promise<Axios>
    ]>
]>

So the top level promise can resolve when all the inner ones do. The code that does that would look very similar:

return function () {
    var newarray = [{ post: [{ message: 'default text' }, { message: 'default text' }] }];

    return Promise.all(newarray.map(function (i) {
        return Promise.all(i.post.map(function (item) {
            return axios.get(someLink).then(function (result) {
                item.message = 'new text';
            });
        }));
    })).then(function () {
        return {
            type: constant.GET_SUCCESS,
            payload: newarray
        };
    }).catch(function (error) {
        return {
            type: constant.GET_ERROR,
            payload: 'no result ' + error
        };
    });
};

You can use arrow functions if you think that improves clarity (I don't):

return () => {
    var newarray = [{ post: [{ message: 'default text' }, { message: 'default text' }] }];

    return Promise.all(newarray.map( i => Promise.all(
        i.post.map( item => axios.get(someLink).then( result => {
            item.message = 'new text';
        }) )
    ))).then( () => ({
        type: constant.GET_SUCCESS,
        payload: newarray
    })).catch( (error) => ({
        type: constant.GET_ERROR,
        payload: 'no result ' + error
    }));
};


General remark: I have removed the callback function from your code. It contradicts the philosophy behind promises to call code continuation callbacks from within them.

Instead of doing this (essentially your code):

function bla(callback) {
   asyncFunction().then(someProcessing).then(callback);
}

do this:

function blaAsync() {
   return asyncFunction().then(someProcessing);
}

Note how the second variant no longer has any dependency on its caller. It simply carries out its task and returns the result. The caller can decide what to do with it:

blaAsync().then(function (result) {
   // what "callback" would do
})

这篇关于redux thunk - 承诺完成后如何在嵌套数组中调度数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆