2016-11-19 3 views
2

У меня есть массив, как такJavascript - Redux санк не ждет каких-либо надежд

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. 
    }) 
} 

Проблема: функция отправки в коде передаст мой исходный массив в редуктор вместо модифицированных один. Я хочу, чтобы отправка посылала новый модифицированный массив. И я думаю, что так должно быть, не так ли?

ответ

1

Сейчас quests переменный просто присваиваются по исходному массиву, потому что map функции возврата пустота, но вам нужно возвратить обещания каждого пункта к quests, так что просто добавьте return ключевое слово, так что ваш код будет так :

let quests = array 
    .map((item) => { 
     return axios.get(getOpenGraphOfThisLink + item.message) 
     .then(result =>{ 
      item.message = (result.data) 
      return result 
     }) 
    }) 
+0

прямолинейно да, но быть в курсе оговорки в моем ответе. –

+0

У меня подобный случай, любая идея, как решить http: // stackoverflow.com/questions/40791724/javascript-redux-thunk-doesnt-wait-for-any-prom-again –

0

Это проблема определения проблемы. Вы, безусловно, относятся к неправильному переменной:

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.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! 
    }) 
} 
+0

return axios work, но добавьте параметр массива, тогда функция не будет работать. поэтому теперь мой код просто добавляет ключевое слово return и работает. –

0

Если я правильно понимаю, вы мутируете array.message после каждого запрос был завершен с result.data.

ИМО, вы не должны делать это

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. 
} 

Не забудьте обработать случай ошибки.

0

Как правило, не рекомендуется использовать функцию для изменения переданных ей элементов.

В этом случае, если некоторые axios.get() s преуспели, а некоторые не удались, вы попали бы в мутантный элемент, который, по всей вероятности, нежелателен.

Вместо этого вы можете сопоставить массив мутированных клонов оригинальных предметов и доставить отображаемый массив вниз по цепочке обещаний.

Предполагая, что не задействованы «геттеры», вы можете использовать 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 
    }); 
}); 

Теперь, если вы действительно хотите, чтобы мутировать исходный массив, вы можете сделать это на все или ничего основе в точке «х» с:

Object.assign(array, arr); 
+0

любое представление об этом случае http://stackoverflow.com/questions/40791724/javascript-redux-thunk-doesnt-wait-for-any-promise-again –

 Смежные вопросы

  • Нет связанных вопросов^_^