数组循环和async wait 配合使用细节记录

184 阅读2分钟

数组循环有一些方式,其中,依次访问数组中的元素,当前数组元素访问完成之后,才进行下一个元素的访问,那我们称为窜行访问,反之,我们称为并行访问。 假设,我们有一个数组 array: [1, 2, 3, 4, 5, 6, 7, 8],下面我们看每种方式的访问效果。

  1. for循环,如下图,是窜行
var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}

const display = async () => {
    for (let index = 0; index < array.length; index++) {
        const randomTime = parseInt(Math.random() * 10000);
        await delay(randomTime);
        console.log(index)
    }
}
display();

结果,串行

image.png

  1. for in 循环
var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}

const display = async () => {
    for (const index in array) {
        const randomTime = parseInt(Math.random() * 10000);
        await delay(randomTime);
        console.log(index)
    }
}
display();

结果,窜行

image.png

  1. for of
var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}
const display = async () => {
    for (const item of array) {
        const randomTime = parseInt(Math.random() * 10000);
        await delay(randomTime);
        console.log(item)
    }
}
display();

结果:

image.png 4. forEach

var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}
array.forEach(async(item) => {
    const randomTime = parseInt(Math.random() * 10000);
    await delay(randomTime);
    console.log(item)
});

结果,如下所示,并行。

image.png 5.map

var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}


array.map(async(item) => {
    const randomTime = parseInt(Math.random() * 10000);
    await delay(randomTime);
    console.log(item)
});

结果,并行

image.png 6. filter

var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}


array.filter(async(item) => {
    const randomTime = parseInt(Math.random() * 10000);
    await delay(randomTime);
    console.log(item)
});

结果,并行;

image.png

  1. reduce
var array = [1, 2, 3, 4, 5, 6, 7, 8];
const delay = (timeout) => {
    return new Promise((resovle) => {
        setTimeout(() => {
            resovle();
        }, timeout);
    })
}

 array.reduce(async(prevalue, currentValue) => {
     await prevalue;
    const randomTime = parseInt(Math.random() * 10000);
    await delay(randomTime);
    console.log(currentValue)
    return currentValue
}, undefined);

结果,窜行

image.png 如果,我要并行,则把prevalue的await去掉即可,没错,这里的prevalue 返回的是一个promise值

结论: for/for of /for in 都可以实现程序的逐步运行,forEach / map /filter是异步实行,如果要实现循环完成,在进行下一步操作,可以配合promise.all,如果要实现程序逐步运行,除了for系列循环方式外,可以使用reduce循环,对preValue值进行await等待,即可实现了。