我使用那个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"
}
但是,解决(确定功能)未调用,原因是上载功能,我无法在中收到然后功能。这意味着我在屏幕上看不到“ 上传完成!”。
已转售:感谢 Roamer-1888
在Pipe中,返回诺言不起作用。我将return this.sendUpload(...)
更改为this.sendUpload(...).then(ok,faild)
并成功。