asynchronous等待承诺

我必须等待func1才能运行func2。 但是由于func1 / 2/3包含承诺,它早打印“定期”。

async function executeAsyncTask () { const res1 = await func1(a,b,c) const res2 = await func2(a,b,c) const res3 = await func2(a,b,c) return console.log(res1 , res2 , res3 ) } executeAsyncTask () 

FUNC1

 class A{ promise_API_CALL(params){ //some code here.. } func1(a,b,c){ //so work here... this.promise_API_CALL(params, function( data, err ) { if(err){console.error(err)} console.log( data ); return data; }); //so work here... console.log("termined") } 

编辑:promise_API_CALL是一个外部库的function

尝试在一个承诺包装api电话。 否则,我看不到你想要的方式:

 func1(a, b, c) { return new Promise((resolve, reject) => { this.promise_API_CALL(params, function(data, err) { if (err) { console.error(err) reject(err); } console.log(data); resolve(data); }); //so work here... console.log("termined") }); } 

为了改进你的代码, executeAsyncTask的定义应该是这样的:

 async function executeAsyncTask () { try { const res1 = await func1(a,b,c) const res2 = await func2(a,b,c) const res3 = await func3(a,b,c) return [res1, res2, res3]; // Return all values from 'each await' as an array } catch (err) { throw 'Promise Rejected'; } } 

正如你所看到的,它使用trycatch来处理错误。 换句话说,如果其中一个await函数被rejectedcatch自动抛出错误。

 // This 'func1 code' from 'Carl Edwards' is the same func1(a, b, c) { return new Promise((resolve, reject) => { promise_API_CALL(params, function(data, err) { if (err) { console.error(err) reject(err); } console.log(data); resolve(data); }); //so work here... console.log("termined") }); } 

最后你可以这样调用executeAsyncTask

 executeAsyncTask().then(function(result) { console.log("result => " + result); // Result of 'res1, res2, res3' }).catch(function(error) { console.log("error => " + error); // Throws 'Promise Rejected' }); 

请记住:

  • 每个async函数都返回一个Promise对象await声明以PromisePromise ,等待Promise resolvereject

  • 你可以使用多次,只要你喜欢


奖金

如果你想要所有你的promise (func1, func2, func3)并行执行(不是一个接一个),你可以像下面这样修改你的executeAsyncTask函数:

 async function executeAsyncTask () { try { return [ res1, res2, res3 ] = await Promise.all([ func1(a,b,c), func2(a,b,c), func3(a,b,c) ]) } catch (err) { throw 'Promise Rejected'; } } 

为了让你的代码工作func1将会是这样的:

 async func1(a,b,c){ const res = await promise_API_CALL(params, function( data, err ) { if(err){console.error(err)} console.log( data ); return data; }); console.log("termined"); return res; } 

然后运行这将工作

 async function executeAsyncTask () { const res1 = await func1(a,b,c); const res2 = await func2(a,b,c); const res3 = await func2(a,b,c); //yada yada yada } 

这个答案与Carl Edward的答案非常接近,但build立在node.js的约定上。

promise_API_CALL()的callback不会首先传递错误,这真的很不幸。 否则,你可以使用util.promisify() 。 另一种方法是遵循node.js的Custom promisified functions 。 它看起来像这样:

 const util = require("util"); promise_API_CALL[util.promisify.custom] = function (params) { return new Promise((resolve, reject) => { promise_API_CALL(params, function (data, err) { if (err) { return reject(err); } resolve(data); }); }); }; 

我看到的唯一的问题是,这样做会改变原来的function(这不是你的,是一个粗鲁的坏习惯)。 但是这个问题稍微得到了缓解,因为它使用ES6的新符号types ,这意味着你不会互相打破。

这是一个完整的例子:

 const util = require("util"); /** * Use to force the API along the failure path * @constant {Boolean} */ const SHOULD_FAIL = false; /** * Callback to deal with API responses * @callback apiCallback * @param {Object} data The data of the response * @param {Error} [err] Optional error that says something went wrong */ /** * Dummy API calling function * @param {Object} kwargs api arguments * @param {apiCallback} cb The callback that handles the response */ function apiCall(kwargs, cb) { setTimeout(() => { // Allow testing of failure path if (SHOULD_FAIL) { return cb(undefined, new Error("Purposefull failure")); } // Success path cb({ foo: "bar" }); }, 1000); } /* * Create a function that wraps the apiCall function in a Promise * and attach it to apiCall's util.promisify.custom Symbol */ apiCall[util.promisify.custom] = function (kwargs) { return new Promise((resolve, reject) => { apiCall(kwargs, (data, err) => { if (err) { return reject(err); } resolve(data); }); }); }; // Create shorthand function to the promisified function const asyncApiCall = util.promisify(apiCall); // Sanity check to make sure that they are the same console.log(`Are promisifies the same? ${asyncApiCall === apiCall[util.promisify.custom]}`); // Run tester function (async function main() { // Do some stuff console.log("Started"); // Use the async func let some_data_from_api; try { some_data_from_api = await asyncApiCall({ fizz: "buzz" }); } catch (err) { console.error(err); } // Print the data after we have it console.log(some_data_from_api); //so work here... console.log("Done") }());