我必须等待func1被定义为运行func2。但由于func1 / 2/3包含promises,因此它会在早期打印出“termined”。
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是外部库的功能
答案 0 :(得分:4)
尝试在承诺中包装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")
});
}
答案 1 :(得分:1)
为了改进您的代码,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';
}
}
如您所见,它甚至使用try
和catch
来处理错误。换句话说,如果其中一个await
函数为rejected
,则catch
会自动抛出错误。
// 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
语句在Promise
上运行,等到Promise
resolve
s或reject
s。
您可以根据需要多次使用await
。
<强>奖金强>:
如果您希望所有承诺(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';
}
}
答案 2 :(得分:0)
为了让代码工作,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
}
答案 3 :(得分:0)
这个答案与Carl Edward's answer密切相关,但建立在node.js&#39;之上。约定。
真的很遗憾,promise_API_CALL()
的回调并没有首先传递错误。否则你可以使用util.promisify()
。一种替代方案是遵循node.js&#39; 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);
});
});
};
我看到的唯一问题是这样做会改变原来的功能(这不是你的,并且有点粗鲁坏习惯)。但问题略有减轻,因为它使用的是ES6的新Symbol type 意味着你不会互相诅咒。
这是一个完整的例子:
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")
}());