JS:如何解决这个承诺的事情?

时间:2017-12-11 05:08:38

标签: javascript promise

解决多重承诺的正确方法是什么?链或.map他们?

let promises = [];
// data is a binary zip file
JSZip.loadAsync(data).then((zip) => {
    for (let filename in zip.files) {
        zip.files[filename].async("blob")
        // ********** Problem! **********
        // because of the following .then, the promises.push is deferred
        // and so the next .then is run immediately
            .then((fileData) => {
                promises.push(this.file.writeFile(...));
            })
    }

    return Promise.all(promises);
}).then(() => {
    ...

2 个答案:

答案 0 :(得分:3)

无法知道,但怀疑zip.files[filename].async("blob")会返回一个解析为fileData的承诺,您应等待zip.files[filename].async("blob")解析。

如果zip.files是一个数组,那么将zip.files映射到promises会更优雅(参见Mehari的答案),如果它是一个对象,那么map(Object.keys(zip.files)将优于for in (除非属性属于zip.files)原型

以下是否有效?

JSZip.loadAsync(data)
.then((zip) => {
    let promises = [];
    for (let filename in zip.files) {
      promises.push(
        zip.files[filename].async("blob")
        // ********** Problem! **********
        // because of the following .then, the promises.push is deferred
        // and so the next .then is run immediately
        .then((fileData) => {
          this.file.writeFile(...)
        })
      )
    }

    return Promise.all(promises);
}).then(() => {

答案 1 :(得分:1)

我不完全确定您使用的异步API,但以下代码段可能会为您提供一些亮点

JSZip.loadAsync(data).then(zip => {
        const files = zip.files;
        const blobs = files.map(filename => {
            return files[filename].async("blob")
        });
        return Promise.all(blobs);
    })
    .then(fileData => {
        fileData.map(file => {
            // TODO... file.writeFile()
        });
    })