Node.js:为什么我的Promise在PUT请求中不起作用?被宠爱

时间:2018-12-13 18:12:00

标签: node.js promise request drive

我使用那个API在云端硬盘中创建了可恢复的上载。 它有效,但是我无法从Promise接收响应数据

这是我的代码:

var fs = require('fs');
var request = require('request');
var mime = require('mime');
var _ = require("underscore");

class resumableUpload {
    constructor(credentials,token,options={}){
        this.credentials = credentials; // object from json credentials
        this.token = token; // object from token credentials
        this.new_token = {};
        this.expiry_token_time = 0;
        this.options = Object.assign({
            size:256*1024,
            retry:-1
        },options)
    }
    refresh_token(){
        return new Promise((ok,faild)=>{
            var now = new Date().getTime();
            if(now>this.expiry_token_time){
                request.post("https://www.googleapis.com/oauth2/v4/token",{
                    form:{
                        refresh_token:this.token.refresh_token,
                        client_id:this.credentials.client_id,
                        client_secret:this.credentials.client_secret,
                        redirect_uri:this.credentials.redirect_uris[0],
                        grant_type:'refresh_token'
                    }
                },(err,httpResponse,body)=>{
                    if(err) faild(err);
                    this.new_token = JSON.parse(body);
                    this.expiry_token_time = now + this.new_token.expires_in*1000;
                    ok(this.new_token.access_token);
                })
            }else{
                ok(this.new_token.access_token);
            }
        })

    }

    /*
        Upload Resumable
        file:{
            name:'name of file',
            path:'path/to/file'
        }

    */
    upload(file){
        return new Promise((ok,faild)=>{
            this.refresh_token().then((access_token)=>{
                console.log(access_token);
                this.file_len = fs.statSync(file.path).size;
                var form = {};
                if(!_.isEmpty(file.name)) form.name = file.name;
                if(!_.isEmpty(file.parents)) form.parents = [file.parents];
                request.post({
                    uri:'https://www.googleapis.com/upload/drive/v3/files?uploadType=resumable',
                    headers:{
                        'Authorization':`Bearer ${access_token}`,
                        'Content-Type':'application/json; charset=UTF-8',
                        'X-Upload-Content-Type':mime.getType(file.path),
                        'X-Upload-Content-Length': this.file_len,
                        'Content-Length':new Buffer(JSON.stringify(form)).length
                    },
                    body:JSON.stringify(form)
                },(err,res,body)=>{
                    if(err || _.isEmpty(res.headers.location)){

                        if ((this.retry > 0) || (this.retry <= -1)) {
                            this.retry--;
                            return this.upload(file); // retry
                        } else {
                            //console.log(body);
                            faild("Over retry");
                        }
                    }else{

                        var location = res.headers.location;
                        //console.log("URL UPLOAD: ",location);
                        this.sendUpload(location,file).then((data)=>{
                            console.log("UPLOAD DONE!!!");
                            ok(data);
                        }).catch((err)=>{
                            console.log("ERROR: ",err);
                            faild(err);
                        });
                    }
                })
            }).catch(faild)

        })
    }
    sendUpload(api,file,start=0){
        return new Promise((ok,faild)=>{
            this.refresh_token().then((access_token)=>{
                var end = parseInt(start+this.options.size-1);
                if(start>=this.file_len) ok("DONE");
                if(end>=this.file_len) end = this.file_len - 1;
                var headers = {
                    'Authorization':`Bearer ${access_token}`,
                    'Content-Length': parseInt(end - start + 1),
                    'Content-Range':`bytes ${start}-${end}/${this.file_len}`
                }
                var uploadPipe = fs.createReadStream(file.path, {
                    start: start,
                    end: end
                })
                uploadPipe.pipe(request.put({uri:api,headers:headers}).on('response',(res)=>{
                    if(res.statusCode == 308){
                        //console.log(res.headers);
                        var new_start = parseInt(res.headers.range.split('-')[1]);
                        console.log("Percent: "+(new_start/this.file_len*100).toFixed(2)+" %");
                        return this.sendUpload(api,file,new_start+1);
                    }else if(res.statusCode == 200 || res.statusCode == 201){
                        console.log("percent: 100 %");
                        //ok({status:"OK"});
                    }
                }).on('error',(err)=>{
                    if ((this.retry > 0) || (this.retry <= -1)) {
                        this.retry--;
                        console.log("Retry Again");
                        return this.sendUpload(api,file,start);
                    }else{
                        faild("Over retry");
                    }
                }).on('data',(data)=>{
                    if(!_.isEmpty(data)){
                        console.log(data.toString());
                        ok(data.toString());
                    }

                }))
            }).catch(faild)

        })
    }

}
module.exports = resumableUpload;

在该代码的 sendUpload 函数中,我将文件拆分为多个块,然后将其上传到驱动器中。 当我上传最后一个块时,服务器将响应 statusCode 为200或201。 它console.log“百分比:100%”,并从该响应接收数据。 我的回复数据如下:

{
 "kind": "drive#file",
 "id": "xxxxxxxxxxxxxxxxxxxxxxxxx",
 "name": "test-video",
 "mimeType": "video/mp4"
}

但是,解决确定功能)未调用,原因是上载功能,我无法在中收到然后功能。这意味着我在屏幕上看不到“ 上传完成!”。

can't see "UPLOAD DONE!!!" in screen

已转售:感谢 Roamer-1888

在Pipe中,返回诺言不起作用。我将return this.sendUpload(...)更改为this.sendUpload(...).then(ok,faild)并成功。

0 个答案:

没有答案