【轉】Promise循環串行執行寫法

【原文連接】 https://segmentfault.com/q/1010000007499416segmentfault

【注】 原文是一篇問答形式的帖子,此處作了小幅度整理; 本文轉於此處,用於本人收藏,查找方便之用。若有侵權,請聯繫刪除。數組

需求是有一個objects數組,其中的元素是每次異步事件須要的參數 異步事件事件接受參數而且串行執行,最終返回一個promise結果promise

Promise.all彷佛是並行的?bash

const PromiseForEach = (objects, asyncDosometing) => {
    return new Promise((resolve, reject) => {
        Promise.all(objects.map((obj) => {
            return new Promise((resolve, reject) => {
                return asyncDosometing(obj).then(resolve, reject);
            });
        })).then(resolve, reject);
    });
};
複製代碼

這樣寫彷佛也是並行的?異步

const PromiseForEach = (objects,asyncDosometing) => {
        let result = Promise.resolve();
        objects.forEach((obj) => {
            result = result.then(asyncDosometing(obj));
        });
        return result;
    }
複製代碼

// 測試結果爲
// 直接打印了「成功」 data爲undefined 以後 一次性打印出全部「number」
// 而不是 每隔2s打印一個number number都打印完後 打印成功 而且data應給是個number數組async

const list = [];
    for (let i = 0; i < 100; ++i) {
        list.push(i);
    }
    PromiseForEach(list, (number) => {

        return new Promise((resolve, reject) => {
            setTimeout(() => {
                console.log(number);
                return resolve(number);
            }, 2000);
        })

    }).then((data) => {
        console.log("成功");
        console.log(data);
    }).catch((err) => {
        console.log("失敗");
        console.log(err)
    });   
複製代碼

兩種寫法貌似有有問題呢
到是用async/await實現了 雖然不知道對不對啊 可是實現了預期測試

const PromiseForEach = async(objects, asyncDosometing) => {
    let result = [];
    for (let obj in objects) {
        try {
            result.push(await asyncDosometing(obj));
        } catch (err) {
            return err;
        }
    }

    return result;
};
複製代碼

請問用Promise實現這種邏輯的正確的寫法是怎麼樣的?求解!謝謝!!!ui

下面是社區人士whbb的回答:

第二種方式的正確的 runjs.cn/code/ilckww… 若是須要返回結果的話, 能夠再加一層 Promisespa

const list = [];
for (let i = 0; i < 100; ++i) {
    list.push(i);
}
複製代碼
function PromiseForEach(arr, cb) {
    let realResult = []
    let result = Promise.resolve()
    arr.forEach((a, index) => {
        result = result.then(() => {
            return cb(a).then((res) => {
                realResult.push(res)
            })
        })
    })

    return result.then(() => {
        return realResult
    })
}

PromiseForEach(list, (number) => {

    return new Promise((resolve, reject) => {
        setTimeout(() => {
            console.log(number);
            return resolve(number);
        }, 100);
    })

}).then((data) => {
    console.log("成功");
    console.log(data);
}).catch((err) => {
    console.log("失敗");
    console.log(err)
}); 
複製代碼

下面是一些雜七雜八的

  • 我一開始使用Promise時,一直找不到在for循環裏面如何使用 promise來控制異步,而且在 循環體外,獲取異步的結果數組。
  • 直到我看見了這個問答,看見了 let result = Promise.resolve() 這個寫法,我赫然開朗。 用一個Promise對象,將異步任務執行完成的結果做爲參數傳遞,而且經過 在then之後,push結果到一個全局的數組裏面,最終獲取到結果。
result = result.then(() => {
            return cb(a).then((res) => {
                realResult.push(res)
            })
        })
複製代碼
  • 好吧,不亂說了。)>_<(
相關文章
相關標籤/搜索