2015-10-22 14 views
51

मैं नई ES7 async सुविधाओं का उपयोग करने की कोशिश कर रहा हूं और मुझे आशा है कि मेरी समस्या को हल करने से भविष्य में दूसरों की मदद मिलेगी।एसिंक फ़ंक्शन का संयोजन + प्रतीक्षा + सेटटाइमआउट

async function asyncGenerator() { 
    // other code 
    while (goOn) { 
     // other code 
     var fileList = await listFiles(nextPageToken); 
     var parents = await requestParents(fileList); 
     // other code 
    } 
    // other code 
    } 

    function listFiles(token) { 
    return gapi.client.drive.files.list({ 
     'maxResults': sizeResults, 
     'pageToken': token, 
     'q': query 
    }); 
    } 

समस्या यह है कि मेरी जबकि पाश बहुत तेजी से चलाता है और स्क्रिप्ट गूगल एपीआई के प्रति सेकंड बहुत अधिक अनुरोध भेजता है,: यह मेरा कोड है जो काम कर रहा है। इसलिए मैं एक नींद समारोह बनाना चाहता हूं जो अनुरोध में देरी करता है। इस प्रकार मैं अन्य कार्यों में देरी के लिए इस फ़ंक्शन का उपयोग भी कर सकता था। अगर अनुरोध में देरी करने का कोई और तरीका है, तो कृपया मुझे बताएं।

वैसे भी, यह मेरा नया कोड है जो काम नहीं करता है। अनुरोध की प्रतिक्रिया को सेटटाइमआउट के भीतर अनाम async फ़ंक्शन पर वापस कर दिया गया है, लेकिन मुझे नहीं पता कि मैं नींद फ़ंक्शन resp प्रतिक्रिया के जवाब कैसे वापस कर सकता हूं। प्रारंभिक async जनरेटर समारोह के लिए।

async function asyncGenerator() { 
    // other code 
    while (goOn) { 
     // other code 
     var fileList = await sleep(listFiles, nextPageToken); 
     var parents = await requestParents(fileList); 
     // other code 
    } 
    // other code 
    } 

    function listFiles(token) { 
    return gapi.client.drive.files.list({ 
     'maxResults': sizeResults, 
     'pageToken': token, 
     'q': query 
    }); 
    } 

    async function sleep(fn, par) { 
    return await setTimeout(async function() { 
     await fn(par); 
    }, 3000, fn, par); 
    } 

मैं पहले से ही कुछ विकल्पों की कोशिश की है: एक वैश्विक चर में प्रतिक्रिया भंडारण और गुमनाम समारोह के भीतर, सो समारोह से इसे वापस कॉलबैक आदि

उत्तर

150

आपका sleep फ़ंक्शन काम नहीं करता है क्योंकि setTimeout (अभी तक?) एक वादा वापस नहीं करता है जो await एड हो सकता है। आप इसे मैन्युअल रूप से promisify करने की आवश्यकता होगी:

function timeout(ms) { 
    return new Promise(resolve => setTimeout(resolve, ms)); 
} 
async function sleep(fn, ...args) { 
    await timeout(3000); 
    return fn(...args); 
} 

Btw, अपने पाश धीमा करने के लिए आप शायद एक sleep समारोह है कि एक कॉलबैक लेता है और इस तरह यह defers उपयोग करने के लिए नहीं करना चाहती। मैं नहीं बल्कि तरह

while (goOn) { 
    // other code 
    var [parents] = await Promise.all([ 
     listFiles(nextPageToken).then(requestParents), 
     timeout(5000) 
    ]); 
    // other code 
} 

parents की गणना कम से कम 5 सेकंड का समय देता है कुछ करने के लिए सलाह देते हैं।

+1

'Promise.all' दृष्टिकोण से प्यार करें। इतना आसान और सुरुचिपूर्ण! –

+0

'var [माता-पिता] 'का संकेत क्या दर्शाता है? मैंने इसे पहले नहीं देखा है और यह – natedog

+1

@NateUsher यह [सरणी विनाशकारी] (https: // stackoverflow) पर एक कठिन बात है।कॉम/क्यू/3 9 86348/1048572) – Bergi

10

setTimeout एक async समारोह नहीं है, तो आप ES7 async-await के साथ इसका उपयोग नहीं कर सकते हैं।

function sleep (fn, par) { 
    return new Promise((resolve) => { 
    // wait 3s before calling fn(par) 
    setTimeout(() => resolve(fn(par)), 3000) 
    }) 
} 

तो फिर तुम ES7 async-इंतजार के साथ इस नई sleep फ़ंक्शन का उपयोग कर सकेंगे:: लेकिन आप ES6 Promise का उपयोग कर अपने sleep समारोह को लागू कर सकता है

var fileList = await sleep(listFiles, nextPageToken) 

कृपया ध्यान दें कि मैं मैं केवल setTimeout के साथ ES7 async/प्रतीक्षा के बारे में आपके प्रश्न का उत्तर दे रहा हूं, हालांकि यह प्रति सेकंड बहुत से अनुरोध भेजने के साथ आपकी समस्या का समाधान करने में मदद नहीं कर सकता है।

+2

आपको लगता है कि ऐसा नहीं करना चाहिए, जब 'fn' errror फेंकता पकड़ा नहीं किया जाएगा। – Bergi

+0

@ बरगी अच्छा बिंदु! –

+0

@ बर्गि मुझे लगता है कि यह 'नए वादे' पर बुलबुला है जहां आप इसे 'sleep.catch' कर सकते हैं। – Dodekeract

0

आप यूटिल मॉड्यूल से promisify फ़ंक्शन का भी उपयोग कर सकते हैं।

const { promisify } = require('util') 
const sleep = promisify(setTimeout) 

async function main() { 
    console.log("Started") 
    console.time("timer") 
    await method() 
    console.timeEnd("timer") 
    console.log("Finished") 
} 


async function method() { 
    await sleep(3000) 
} 

main() 
संबंधित मुद्दे