deferred/promise 多个 firebase 存储上传的 js 机制

deferred/promise js mecanism on multiple firebase storage upload

我在我的项目中被图像上传到 firebase 数据库异步机制所困扰,这是我的问题:

我有一个表格,用户可以在其中输入一些信息,用户还需要提供 4 张照片才能完成上传过程。

我使用 firebase 数据库和 firebase 存储来处理这个,流程如下:

所以我的交易是仅在设置了 4 张照片 url 时创建和发送字典,我听说过 deferred/promise 概念,但我看到很多 Ajax 请求,没有人有类似的问题,这是我现在所拥有的

$("#submit-bag").click(function () {

    var uploadDfdimg1 = function() {
        var deferred = new $.Deferred();
        var uploadTask = storageRef.child('images/' + $img1.name).put($img1);
        uploadTask.on('state_changed', function(snapshot){
        }, function(error) {
        deferred.reject(error);
        }, function() {
        var downloadURL = uploadTask.snapshot.downloadURL;
        console.log(downloadURL);
        url1 = downloadURL;
        deferred.resolve(downloadURL);

        return deferred.promise();
        });
    }
    var uploadDfdimg2 = function() {
        var deferred = new $.Deferred();
        var uploadTask = storageRef.child('images/' + $img2.name).put($img2);
        uploadTask.on('state_changed', function(snapshot){
        }, function(error) {
        deferred.reject(error);
        }, function() {
        var downloadURL = uploadTask.snapshot.downloadURL;
        console.log(downloadURL);
        url2 = downloadURL;
        deferred.resolve(downloadURL);

        return deferred.promise();
        });
    }
    $.when(uploadDfdimg1,uploadDfdimg2).then(
        function(){console.log('double trouble success')},
        function(){console.log(url1 + " deferred")},
        function(){console.log(url2 + " deferred")});


    var brand = $("#select1 option:selected").text()
    var mail = document.getElementById('form1').value
    var postal_code = document.getElementById('form2').value
    var comment = document.getElementById('comment').value
    //UPLOAD IMG

    //uploadImg(img1,url1);
    //uploadImg(img2,url2);
    uploadImg(img3,url3);
    uploadImg(img4,url4);

    //console.log(url1);
    //console.log(url2);
    console.log(url3);
    console.log(url4);
    //PHOTO LINK VAR
    var postData = {
        marque: brand,
        email: mail,
        code_postal: postal_code,
        commentaire: comment,
        //PHOTO LINK
        validation: 0
    };
    var newPostKey = firebase.database().ref().child('submission').push().key;
    var updates = {};
    updates['/submission/' + newPostKey] = postData;
    firebase.database().ref().update(updates)

就像你在这里看到的那样,img3 和 img4 使用旧的非功能性方式上传自己(downloadUrl 在所有字典 PostData 发送后出现)

对于 img1 和 img2,我尝试使用 Deferred 来查看我是否可以在 $.when.().then 被解雇时同时获得 2 url,通常是在两者的成功承诺之后uploadDfdimg 函数

结果是,我立即得到带有空 url 变量的 "double trouble" 日志消息,通常在一秒钟后,firebase 为 img3 和 img4[返回的两个 url

return log of the above code

我怎样才能将 4 个图像异步发送到 firebase,获取 url,并在此过程结束时,将 url 放入我的字典中以将其发送到我的数据库?

问题似乎要求以下类型的方法。

首先是一个效用函数,它承诺上传过程并交付承诺包装的 downloadURL

function uploadImg(img) {
    return $.Deferred(function(dfrd) {
        var uploadTask = storageRef.child('images/' + img.name).put(img);
        uploadTask.on(
            'state_changed', 
            function(snapshot) {}, 
            function(error) { dfrd.reject(error); }, 
            function() { dfrd.resolve(uploadTask.snapshot.downloadURL); }
        );
    }).promise();
}

现在,该实用程序可用于创建 4 x promise,然后可以将其与 $.when() 聚合:

$("#submit-bag").click(function () {
    var p1 = uploadImg(img1);
    var p2 = uploadImg(img2);
    var p3 = uploadImg(img3);
    var p4 = uploadImg(img4);
    $.when(p1, p2, p3, p4).then(function(downloadUrl1, downloadUrl2, downloadUrl3, downloadUrl4) {
        // Whatever you want to do with downloadUrl1, downloadUrl3, downloadUrl3, downloadUrl4, ...
        // ... do it somewhere in this function.
        var updates = {};
        updates['/submission/' + firebase.database().ref().child('submission').push().key] = {
            marque: $("#select1 option:selected").text(),
            email: $('#form1').val(),
            code_postal: $('#form2').val(),
            commentaire: $('#comment').val(),
            validation: 0
        };
        firebase.database().ref().update(updates);
    });
}

更简洁,你可能会写:

$("#submit-bag").click(function () {
    var promises = [img1, img2, img3, img4].map(uploadImg);
    $.when.apply(null, promises).then(function(downloadUrl1, downloadUrl3, downloadUrl3, downloadUrl4) {
        // Whatever you want to do with downloadUrl1, downloadUrl3, downloadUrl3, downloadUrl4, ...
        // ... do it somewhere in this function.
        // etc, as above
    });
}