使用某些异步操作按顺序迭代的最佳方法

时间:2018-02-20 17:37:04

标签: javascript node.js async-await

我希望在应用一些异步操作时,通过多个数组迭代按顺序

是否有另一种方法可以获得可在Node中运行的Array迭代器?有没有办法摆脱回调?

    let viewModel = {
    pages: [
        {
            id: 'pageOne',
            states: [
                {
                    id: 'stateOne'
                },
                {
                    id: 'stateTwo'
                },
                {
                    id: 'stateThree'
                }
            ]
        },
        {
            id: 'pageTwo',
            states: [
                {
                    id: 'stateOne'
                },
                {
                    id: 'stateTwo'
                },
                {
                    id: 'stateThree'
                }
            ]
        }
    ]
};

function* arrayIterator(_array){
    while(_array.length > 0) yield _array.shift();
}

function loadBrowser(){
    return pseudoAsync('loaded browser');
}

function stateActions(state){
    return pseudoAsync('actioning: ' + state.id);
}

function processState(state, states, callback) {
    if(!state.done) {
        console.log(state.value.id);
        stateActions(state.value).then(()=>{
            processState(states.next(), states, callback);
        });
    } else {
        callback();
    }
}

function processPage(page, pages) {
    if(!page.done){
        console.log(page.value.id);
        loadBrowser().then(()=>{
            let states = arrayIterator(page.value.states);
            processState(states.next(), states, ()=>{
                processPage(pages.next(), pages);
            });
        });
    }
}

let pages = arrayIterator(viewModel.pages);
processPage(pages.next(), pages);


function pseudoAsync(message){
    return new Promise((resolve, reject)=>{

        setTimeout(()=>{
            console.log(message);
            resolve();
        }, 2000)

    });

}

Plunker

这是预期的输出顺序:

  • PAGEONE
  • 已加载浏览器
  • stateOne
  • 行动:stateOne
  • stateTwo
  • 行动:stateTwo
  • stateThree
  • 行动:stateThree
  • pageTwo
  • 已加载浏览器
  • stateOne
  • 行动:stateOne
  • stateTwo
  • 行动:stateTwo
  • stateThree
  • 行动:stateThree

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

由于您已经标记了问题async / await,为什么不直接使用它呢?

for (const page of viewModel.pages) {
    console.log(page.id);
    await loadBrowser();
    for (const state of page.states) {
        console.log(state.id);
        await stateActions(state);
    }
}
  

是否有另一种方法可以获得可在Node中使用的Array迭代器?

当然:arr[Symbol.iterator]()arr.values()。它由for … of暗中使用。

  

有没有办法可以摆脱回调?

正确使用promises,不要尝试手动推进迭代器。