2017-07-02 194 views
0

我使用es6並有以下承諾。我想要的是下一個Promise.all來等待之前的Promise.all在完成下一個之前完成。我試着用下面的代碼,但它不工作,只有Promise 1已解決。如何嵌套promise.all

var deletePromises = []; 
arr.menuItems.forEach((item, idx) => { 
    if (item.replace) { 
    deletePromises.push(deleteFromFirebase(user.uid, item)); 
    } 
}); 

// Promise 1 
Promise.all(deletePromises).then(res1 => { 
    var uploadPromises = [], updateRecordPromises = []; 

    arr.menuItems.forEach((item, idx) => { 
    uploadPromises.push(uploadToFirebase(user.uid, item)); 
    }); 

    // Promise 2 
    Promise.all(uploadPromises).then(res2 => { 
    arr.menuItems.forEach((item, idx) => { 
     item.replace = false; 
     updateRecordPromises.push(updateRecord(user.uid, item)); 
    }); 

    // Promise 3 
    Promise.all(updateRecordPromises).then(res3 => { 
     console.log('All promise execute with successfully'); 
    }); 
}); 
}); 

MarkM回答

嘗試使用鏈接馬克建議,但問題仍然存在。我發現問題出在哪裏,這是uploadPromises永不解決,然後永遠不會被調用。

uploadToFirebase功能

困在這裏,但文件上傳成功。我可以看到所有的文件。

const uploadToFirebase = (userid, item) => { 
return new Promise((resolve, reject) => { 
    const uploadUri = Platform.OS === "ios" 
     ? RNFetchBlob.wrap(item.pic_url.replace("file://", "")) 
    : RNFetchBlob.wrap(item.pic_url); 

    Blob.build(uploadUri, { 
     type: "image/png;" 
    }).then(blob => { 
    // upload image using Firebase SDK 
    firebase 
    .storage() 
    .ref("menu_items") 
    .child(userid) 
    .child(item.new_filename) 
    .put(blob, { contentType: "image/png" }) 
    .then(snapshot => { 
     console.log("Promise resolve: ", snapshot); 
     resolve(snapshot); 
     blob.close(); 
    }) 
    .catch(error => { 
     reject(error.message); 
    }); 
    }); 
}); 
}; 

更新代碼

的console.log( '打印RES2')不打印

var deletePromises = [], 
uploadPromises = [], 
updateRecordPromises = []; 

arr.menuItems.forEach((item, idx) => { 
    if (item.replace) { 
    deletePromises.push(deleteFromFirebase(user.uid, item)); 
    } 
}); 

Promise.all(deletePromises) 
.then(res1 => { 
    console.log("Print res1:", res1); 
    arr.menuItems.forEach((item, idx) => { 
    uploadPromises.push(uploadToFirebase(user.uid, item)); 
    }); 

    return Promise.all(uploadPromises); 
}) 
.then(res2 => { 
    console.log("Print res2:", res2); 
    dispatch({ type: MENU_UPDATE_SUCCESS, payload: arr }); 
    dispatch(reset("menuItem")); 
}) 
.catch(error => { 
    console.log("Print error:", error); 
}); 
+0

'Promise.all'返回一個承諾,當所有承諾傳遞給promise.all時,承諾解決。所以你可以''然後''Promise.all'調用像正常的'Promise'流 –

+0

我試圖調試console.log然後promise2。好像它已經完全解決了,但是沒有進入,試着在promise2的console.log中,但沒有打印任何東西。我在這裏做錯了什麼? – digit

回答

0

我找到了解決方案。這是因爲menuItems array prop - > new_filename之一是空的,這就是爲什麼promise永遠不會得到解決。所以,我只需要爲每個道具添加空檢查,然後正確解決承諾。感謝@MarkM的答案。現在,與嵌套承諾相比,代碼更清晰,更易於閱讀。

Promise.all(deletePromises) 
.then(res1 => { 
    console.log("Print res1:", res1); 
    arr.menuItems.forEach((item, idx) => { 
    if (!isEmpty(item.new_filename)) { 
     uploadPromises.push(uploadToFirebase(user.uid, item)); 
    } 
    }); 

    return Promise.all(uploadPromises); 
}) 
.then(res2 => { 
    console.log("Print res2:", res2); 
    dispatch({ type: MENU_UPDATE_SUCCESS, payload: arr }); 
    dispatch(reset("menuItem")); 
}) 
.catch(error => { 
    console.log("Print error:", error); 
}); 
+0

很高興你有它的工作。 –

3

你不需要巢的承諾,你可以回到你的新Promise.allthen(),這將讓你鏈接他們。舉個簡單的例子:

var arr = [1, 2, 3, 4, 5, 6] 

function slowF(i) { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => resolve(i), i*200) 
    }) 
} 
var p = arr.map((i) => slowF(i)) 


Promise.all(p) 
.then((p) => { 
    console.log("In first Promise.all resolving: ", p) 
    var newP = p.map(i => slowF(i)) 
    return Promise.all(newP) 
}) 
.then((p)=>{ 
    console.log("In second Promise.all resolving: ", p) 
}) 
.catch((e) => console.log("error: ", e)) 
+0

查看我更新的問題。 – digit