[英]Async await of a promise
我必須等待func1被定義為運行func2。 但由於func1 / 2/3包含承諾,因此它會在早期打印出“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是外部庫的功能
嘗試在承諾中包裝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';
}
}
正如您所看到的,它使用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
或reject
s。
您可以根據需要多次使用await
。
獎金 :
如果你想要所有的promises (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的答案密切相關,但建立在node.js的約定之上。
非常不幸的是, promise_API_CALL()
的回調不會先傳遞錯誤。 否則你可以使用util.promisify()
。 一種替代方法是遵循node.js的Custom promisified函數 。 它看起來像這樣:
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的新符號類型 應該意味着你就不會破壞對方。
這是一個完整的例子:
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")
}());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.