2017-03-14 107 views
1

嗨,我試着寫的承諾要求一些下載的功能,但如果我有一個超時我不能處理這個錯誤,我嘗試MENY的例子,但仍然有這個錯誤請求承諾未處理拒絕RequestError:錯誤:ETIMEDOUT

Unhandled rejection RequestError: Error: ETIMEDOUT 
    at new RequestError (/home/parse/node_modules/request-promise-core/lib/errors.js:14:15) 
    at Request.plumbing.callback (/home/parse/node_modules/request-promise-core/lib/plumbing.js:87:29) 
    at Request.RP$callback [as _callback] (/home/parse/node_modules/request-promise-core/lib/plumbing.js:46:31) 
    at self.callback (/home/parse/node_modules/request/request.js:186:22) 
    at emitOne (events.js:101:20) 
    at Request.emit (events.js:191:7) 
    at Timeout._onTimeout (/home/parse/node_modules/request/request.js:816:16) 
    at ontimeout (timers.js:380:14) 
    at tryOnTimeout (timers.js:244:5) 
    at Timer.listOnTimeout (timers.js:214:5) 

我的代碼

功能下載:

function downloadPhoto(url,uploadUrl,name){ 
    return new Promise(function(resolve, reject){ 
     rp(url,{timeout:15000},function(e){if(e) reject(e);}).on('error', function(e){return reject(e);}).pipe(fs.createWriteStream(name+'.jpg')).on('finish',() => { 
     //console.log('done Download photo'); 
     return resolve(); 
    }); 
    }); 

} 

調用這個函數

function sndPht(url,uploadUrl){ 
    return new Promise(function(resolve, reject){ 
     return downloadPhoto(url,uploadUrl,name).then(function(){ 
      ..... some logic ..... 
     }).catch(function(err){ 
      return reject(err); 
     }); 
} 

許多文件我調用函數藍鳥JS地圖:

Promise.map(photos, function(photo) { 
    if(photo.type === 'photo'){ 
    return sndPht(photo,uploadUrl); 
    } 
},{concurrency: 1}); 

我該怎麼辦了?

+0

是什麼'sndPht' –

+0

@JaromandaX對不起,UPD後。 – izac

+0

所以,這是對'sndPht'返回的諾言的未處理拒絕,這是問題 –

回答

1

我有一個解決方案,如果你使用一個請求答應你喊創建的承諾和回報他,趕上exeption,它在我的情況不帶管的工作,像這樣,我們需要改變功能下載喜歡

function downloadPhoto(url){ 
    var options = { 
     uri:url, 
     timeout:10000, 
     encoding: 'binary' 
    }; 

    return rp(options); 
} 

,然後我們可以使用它像

return downloadPhoto(url).then(function(file){ 
     fs.writeFileSync(name+'.jpg', file, 'binary'); 
    }).catch(function(err){ 
    console.log(err); 
}); 

,我們可以使用地圖

Promise.map(photos, function(photo) { 
    if(photo.type === 'photo'){ 
    return sndPht(photo,uploadUrl); 
    } 
},{concurrency: 1}); 

但如果你需要downlod大的文件,你需要使用帶有請求calback的

1

您可以使用Promise.race來使用解析或拒絕的第一個承諾中的值。

使用這種技術,如果下載時間過長,我們可能會出現一段時間後超時的錯誤。該downloadPhoto承諾仍然解決,但它不會被處理

const images = [ 
 
    { url: 'www.foo.com', uploadUrl: '/foo', name: 'foo' } 
 
, { url: 'www.bar.com', uploadUrl: '/bar', name: 'bar' } 
 
, { url: 'www.baz.com', uploadUrl: '/baz', name: 'baz' } 
 
] 
 

 
const promiseTimeout = (delay, promise) => 
 
    Promise.race([ 
 
    new Promise((resolve, reject) => 
 
     setTimeout(resolve, delay, { 
 
     status: 'error', 
 
     msg: 'took too long!' 
 
     }) 
 
    ), 
 
    promise 
 
    ]) 
 

 
const downloadPhoto = ({ url, uploadUrl, name }) => 
 
    promiseTimeout(
 
    1000, 
 
    new Promise((resolve, reject) => { 
 
     setTimeout(resolve, 3000, { 
 
     status: 'success', 
 
     msg: `this will never resolve ${url}` 
 
     }) 
 
    }) 
 
) 
 

 
// map images array [...image] into [...Promise(image)] 
 
const imagePromises = images.map(downloadPhoto) 
 
// resolve all promises 
 
Promise.all(imagePromises) 
 
// called once all promises are resolved with array of results 
 
.then(images => { 
 
    // map over the resolved images and do further processing 
 
    images.map(console.log.bind(console, 'Image resolved')) 
 
}) 
 
// promises no longer reject, you will need to look at the status 
 
.catch(console.log.bind(console, 'Error: '))

+0

好的thx,但我可以,我可以在Promise.map循環中使用它? – izac

+0

我已經更新了答案,以便您解決圖像數組的承諾。你沒有包含圖像對象結構,所以我只是猜測。 'promiseTimeout'現在被抽象來包裝一個承諾。並且Promise不會再拒絕,因爲這會導致'Promise.all'的問題,因此在映射結束時您需要檢查狀態。 – synthet1c

+0

它的工作,但1)你錯過promiseTimeout不解析函數setTimeout只拒絕(如果時間結束然後拒絕) 2)超時工作,但不停止一個程序請求等待,然後拋出錯誤,如果我有很多文件,然後程序在瞬間工作拋出停止,如果我有1-2個文件程序下載,然後等待請求異常 – izac

相關問題