2016-10-08 4 views
2

Этот код здесь загружает данные с помощью действий и будет серией, но его будет трудно редактировать, добавьте еще одну загрузку API, а синтаксис не ясен.как реорганизовать водопад .then()

this.props.loadNutMatrixes({perPage:'all'}).then(()=>{ 
 
     this.props.loadIngredients().then(()=>{ 
 
     this.props.getBadge().then(()=>{ 
 
      this.props.loadNutInfoItems({perPage:'all'}).then(()=>{ 
 
      this.props.getItemSize().then(()=>{ 
 
       this.props.getSingleMenuCategory(this.props.category_uid).then(()=>{ 
 
       this.props.loadAllStores(({per_page:'all'})).then(()=>{ 
 
        if (this.props.selectedMenuItem){ 
 
        initialize("addNewMenuItem", { 
 
         ...this.props.selectedMenuItem 
 
        }) 
 
        } 
 
       }) 
 
       }) 
 
      }) 
 
      }) 
 
     }) 
 
     }) 
 
    })

ответ

5

Вы можете преобразовать это в вертикальную структуру, приковав обещания вместо вложенности:

this.props.loadNutMatrixes({perPage:'all'}) 
    .then(() => this.props.loadIngredients()) 
    .then(() => this.props.getBadge()) 
    .then(() => this.props.loadNutInfoItems({perPage:'all'})) 
    .then(() => this.props.getItemSize()) 
    .then(() => this.props.getSingleMenuCategory(this.props.category_uid)) 
    .then(() => this.props.loadAllStores(({per_page:'all'}))) 
    .then(() => { 
    if (this.props.selectedMenuItem) { 
     initialize("addNewMenuItem", { 
     ...this.props.selectedMenuItem 
     }) 
    } 
    }); 

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

loadAllNutMatrixes() { 
    return this.loadNutMatrixes({ perPage: 'all' }); 
} 

loadAllNutInfoItems() { 
    return this.loadNutInfoItems({ perPage: 'all' }); 
} 

getSingleMenuCategoryFromId() { 
    return this.getSingleMenuCategory(this.category_uid); 
} 

loadEveryStory() { 
    return this.loadAllStores({ perPage: 'all' }); 
} 

Тогда вы могли бы реорганизовать последний шаг в свой собственный метод:

onChainFinished() { 
    if (this.props.selectedMenuItem) { 
    initialize("addNewMenuItem", { 
     ...this.props.selectedMenuItem 
    }) 
    } 
} 

И объединить два с некоторой деструктуризацией добиться более чистой цепи:

const { props } = this; 
props.loadAllNutMatrixes() 
    .then(props.loadIngredients) 
    .then(props.getBadge) 
    .then(props.loadAllNutInfoItems) 
    .then(props.getItemSize) 
    .then(props.getSingleMenuCategoryFromId) 
    .then(props.loadEveryStore) 
    .then(this.onChainFinished); 

EDIT основанных на ваш комментарии

используя что-то вроде promise.all но в серии!

Существует нет встроенного метода для объединения обещаний, но вы можете создать вспомогательный метод, подходящий для вашего случая использования. Вот общий пример:

// `cp` is a function that creates a promise and 
// `args` is an array of arguments to pass into `cp` 
chainPromises([ 
    { cp: this.props.loadNutMatrixes, args: [{perPage:'all'}] }, 
    { cp: this.props.loadIngredients }, 
    { cp: this.props.getBadge }, 
    { cp: this.props.loadNutInfoItems, args: [{perPage:'all'}] }, 
    { cp: this.props.getItemSize }, 
    { cp: this.props.getSingleMenuCategory, args: [this.props.category_uid] }, 
    { cp: this.props.loadAllStores, args: [{per_page:'all'}] } 
]).then(() => { 
    if (this.props.selectedMenuItem) { 
    initialize("addNewMenuItem", { 
     ...this.props.selectedMenuItem 
    }) 
    } 
}); 

function chainPromises(promises) { 
    return promises.reduce(
    (chain, { cp, args = [] }) => { 
     // append the promise creating function to the chain 
     return chain.then(() => cp(...args)); 
    }, Promise.resolve() // start the promise chain from a resolved promise 
); 
} 

Если вы используете один и тот же подход, что и выше, чтобы реорганизовать методы с аргументами, было бы убрать этот код, как хорошо:

const { props } = this; 
chainPropsPromises([ 
    props.loadAllNutMatrixes, 
    props.loadIngredients, 
    props.getBadge, 
    props.loadAllNutInfoItems, 
    props.getItemSize, 
    props.getSingleMenuCategoryFromId, 
    props.loadEveryStory 
]) 
.then(this.onChainFinished); 

function chainPropsPromises(promises) { 
    return promises.reduce(
    (chain, propsFunc) => (
     chain.then(() => propsFunc()); 
    ), Promise.resolve() 
); 
} 
+0

они должны быть последовательно, так что они не могут быть в promise.all, но вертикальная структура была прохладной, но это так же, как отступ рефакторинг, я хочу синтаксис рефакторинга! –

+0

Что вы подразумеваете под синтаксисом рефакторинга? – nem035

+0

используя что-то вроде prom.all, но последовательно! –

0

Возвращение обещания цепи его к внешнему обещанию.

this.props.loadNutMatrixes({perPage:'all'}).then(()=>{ 
    return this.props.loadIngredients() 
}) 
.then(()=>{ 
    return this.props.getBadge() 
}) 
.then(()=>{ 
    return this.props.loadNutInfoItems({perPage:'all'}) 
}) 
.then(()=>{ 
    return this.props.getItemSize() 
}) 
.then(()=>{ 
    return this.props.getSingleMenuCategory(this.props.category_uid) 
}); 

... 
0

Если обещания не зависят от друг с другом, я бы использовал Promise.all:

const {props} = this; 
Promise.all([ 
    props.loadNutMatrixes({perPage: 'all'}), 
    props.loadIngredients(), 
    props.getBadge(), 
    props.loadNutInfoItems({perPage: 'all'}), 
    props.getItemSize(), 
    props.getSingleMenuCategory(props.category_uid), 
    props.loadAllStores(({per_page: 'all'})), 
]).then(() => { 
    if (props.selectedMenuItem) initialize("addNewMenuItem", {...props.selectedMenuItem}); 
}); 
+0

они не зависят друг от друга, а должны быть рядом, в 'Promise.all', все они вызываются параллельно! –

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