جافاسكريبت - رفع ملفات كبيرة على أجزاء باستخدام Node.js


أنا أحاول رفع ملفات كبيرة جدًا على خادم على دفعات. جانب الخادم يعمل بشكل ممتاز. في الدالة التي قمت بابتكارها، تحاول رفع جميع الملفات مرة واحدة. أنا جديد على async/await ولست متأكدًا كيف أتابع. الهدف هو رفع واحد فقط في كل مرة على دفعات.

لاحظ أنني قد قمت باستخراج هذا من فصل دراسي، وقمت بتحديثه من أجل الوضوح، وأزلت كل الأجزاء غير الضرورية.

استخدام node-fetch لإضافة fetch().

شكراً على أي مساعدة أو نصيحة :)

let tree = []

const start = () => {
    scan('/foo/bar', err => { 
        tree.forEach(file => {
            upload(file)
        })
    })
}

const scan = dir => { ... } // assigns array of files to tree

const upload = file => {
    const stream = fs.createReadStream(file) 
    stream.on('data', async chunk => {
        stream.pause()
        try {
            let response = await fetch('https://some/endpoint', {
                method: 'post',
                body: JSON.stringify({
                    file: file,
                    chunk: chunk.toString('base64')
                }) 
            })
            stream.resume()
        } catch(e) {
            // handle errors
        }
    })
    stream.on('end', () => {
       console.log('end', file)
    })
    stream.on('error', err => {
        console.log('error', err)
    })
}

الإجابة رقم 1

Array.prototype.forEach يعمل بشكل تزامني حتى تتم معالجة جميع عناصر المصفوفة، متجاهلًا أي قيمة يتم إرجاعها بواسطة دالة الوسيط التي يستدعيها.

لتحميل ملف واحد في كل مرة، حاول استخدام await (داخل دالة غير متزامنة) للانتظار حتى يتم تحميل كل ملف، جنبًا إلى جنب مع إرجاع وعد (Promise) من عملية التحميل يتم الوفاء به عند اكتمال التحميل. من الناحية المفاهيمية (دون التعامل بأخطاء بطريقة سلسة) قد يبدو الأمر كالتالي

const uploadTree = async tree => {
    for( file of tree) {
         await uploadFile( file); // process files one at a time
    }
}

// wrap the existing upload code in a promise executor:

const uploadFile = file => new Promise( (resolve, reject) => {
     const stream = fs.createReadStream(file)
     stream.on('data' ...
        ...
     } catch(e) {
        console.log( "Error uploading chunk of %s", file)
        reject(e) // handle errors
     }
     stream.on('end', resolve)
     stream.on('error', e=> {
        console.log(" Error reading %s", file)
        reject (e)
     })
});

// upload complete tree array files:

uploadTree(tree)
.then( ()=> console.log( "tree uploaded successfully"));
.catch( err=> console.log("An upload failed: ", err));