Promise.all 奇怪的分辨率问题
Promise.all strange resolution issue
调用时考虑这两个函数
getStatusAll(数据)-
data=[[],['1'],['2'],['3']];
async function getStatusAll(data) {
console.log("In getStatusAll");
try{
let statusPromiseArray = data.map(async(value) => {
result= await this.fetchStatusDBs(value);
return result;
});
statusResolvedArray= await Promise.all(statusPromiseArray)
return statusResolvedArray;
}catch(err){
throw(err);
}
}
async function fetchStatusDBs(data) {
console.log("In fetchStatusDBs");
try{
//fetch status in dvf_req_id for an dvf_req_id
if(data.length==0){
console.log("1");
dvfStatus = await Promise.resolve("Disabled");
console.log("2");
trainingStatus = await Promise.resolve("Disabled");
console.log("3");
inferenceStatus = await Promise.resolve("Disabled");
}
else {
console.log("4");
dvfStatus = await Promise.resolve("Enabled");
console.log("5");
trainingStatus = await Promise.resolve("Enabled");
console.log("6");
inferenceStatus = await Promise.resolve("Enabled");
}
return [dvfStatus,trainingStatus,inferenceStatus];
}catch(err){
throw(err);
}
}
我正在尝试解决 Promise.all 中的多个 Promise
但结果出人意料。
实际输出-
In getStatusAll
In fetchStatusDBs
1
In fetchStatusDBs
4
In fetchStatusDBs
4
In fetchStatusDBs
4
2
5
5
5
3
6
6
6
[["Enabled","Enabled","Disabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"]]
预期输出-
In getStatusAll
inside map
In fetchStatusDBs
1
2
3
inside map
In fetchStatusDBs
4
5
6
inside map
In fetchStatusDBs
4
5
6
inside map
In fetchStatusDBs
4
5
6
[["Disabled","Disabled","Disabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"]]
但是像这样更改 fetchStatusDBs returns 以正确的格式输出。
async function fetchStatusDBs(data) {
console.log("In fetchStatusDBs");
try{
if(data.length==0){
dvfStatus = "Disabled";
trainingStatus = "Disabled";
inferenceStatus = "Disabled";
}
else {
dvfStatus = "Enabled";
trainingStatus = "Enabled";
inferenceStatus = "Enabled";
}
return [dvfStatus,trainingStatus,inferenceStatus];
}catch(err){
throw(err);
}
}
有人可以帮我吗?
您的主要问题是 fetchStatusDBs
中的状态变量未声明,因此 implicitly global。由于您的代码正在进行多个并发调用,这些调用在 await
暂停点处交错,因此它们相互影响 - 一个典型的竞争条件。要解决此问题,只需使用 let
或 var
.
声明变量
const data=[[],['1'],['2'],['3']];
async function getStatusAll(data) {
console.log("In getStatusAll");
let statusPromiseArray = data.map(this.fetchStatusDBs, this);
return Promise.all(statusPromiseArray);
}
async function fetchStatusDBs(data) {
console.log("In fetchStatusDBs");
let dvfStatus, trainingStatus, inferenceStatus;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//fetch status in dvf_req_id for an dvf_req_id
if (data.length==0) {
console.log("1");
dvfStatus = await Promise.resolve("Disabled");
console.log("2");
trainingStatus = await Promise.resolve("Disabled");
console.log("3");
inferenceStatus = await Promise.resolve("Disabled");
} else {
console.log("4");
dvfStatus = await Promise.resolve("Enabled");
console.log("5");
trainingStatus = await Promise.resolve("Enabled");
console.log("6");
inferenceStatus = await Promise.resolve("Enabled");
}
return [dvfStatus, trainingStatus, inferenceStatus];
}
这将得到预期的结果(return 值)。为了从日志中获得预期的输出,您不能将 map
与异步函数一起使用,然后使用 Promise.all
等待所有承诺,但您需要按顺序进行调用:
async function getStatusAll(data) {
console.log("In getStatusAll");
const statusArray = [];
for (const value of data) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^
statusArray.push(await this.fetchStatusDBs(value));
// ^^^^^
}
return statusArray ;
}
你对async-await有几个误解
async function getStatusAll(data) {
console.log("In getStatusAll");
<del>try{</del>
let statusPromiseArray = data.map(async(value) => { // map is sync
result= await this.fetchStatusDBs(value); // global result
return result; // return-await anti-pattern
});
statusResolvedArray= await Promise.all(statusPromiseArray) // global
return statusResolvedArray; // return-await anti-pattern
<del>}catch(err){</del> // catch-throw anti-pattern
<del>throw(err);</del>
<del>}</del>
}
所有这些都可以写成-
function getStatusAll(data) {
return Promise.all(data.map(v => this.fetchStatusDBs(v)))
}
任何错误都会自动冒出来。无需catch
和重新throw
。这将在 并行 中执行所有提取。如果需要,您可以在 serial 中执行请求。这表明在 async
-
中正确使用 await
async function getStatusAll(data) {
const result = []
for (const value of data)
result.push(await this.fetchStatusDBs(value))
return result
}
调用时考虑这两个函数 getStatusAll(数据)-
data=[[],['1'],['2'],['3']];
async function getStatusAll(data) {
console.log("In getStatusAll");
try{
let statusPromiseArray = data.map(async(value) => {
result= await this.fetchStatusDBs(value);
return result;
});
statusResolvedArray= await Promise.all(statusPromiseArray)
return statusResolvedArray;
}catch(err){
throw(err);
}
}
async function fetchStatusDBs(data) {
console.log("In fetchStatusDBs");
try{
//fetch status in dvf_req_id for an dvf_req_id
if(data.length==0){
console.log("1");
dvfStatus = await Promise.resolve("Disabled");
console.log("2");
trainingStatus = await Promise.resolve("Disabled");
console.log("3");
inferenceStatus = await Promise.resolve("Disabled");
}
else {
console.log("4");
dvfStatus = await Promise.resolve("Enabled");
console.log("5");
trainingStatus = await Promise.resolve("Enabled");
console.log("6");
inferenceStatus = await Promise.resolve("Enabled");
}
return [dvfStatus,trainingStatus,inferenceStatus];
}catch(err){
throw(err);
}
}
我正在尝试解决 Promise.all 中的多个 Promise 但结果出人意料。 实际输出-
In getStatusAll In fetchStatusDBs 1 In fetchStatusDBs 4 In fetchStatusDBs 4 In fetchStatusDBs 4 2 5 5 5 3 6 6 6 [["Enabled","Enabled","Disabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"]]
预期输出-
In getStatusAll inside map In fetchStatusDBs 1 2 3 inside map In fetchStatusDBs 4 5 6 inside map In fetchStatusDBs 4 5 6 inside map In fetchStatusDBs 4 5 6 [["Disabled","Disabled","Disabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"],["Enabled","Enabled","Enabled"]]
但是像这样更改 fetchStatusDBs returns 以正确的格式输出。
async function fetchStatusDBs(data) {
console.log("In fetchStatusDBs");
try{
if(data.length==0){
dvfStatus = "Disabled";
trainingStatus = "Disabled";
inferenceStatus = "Disabled";
}
else {
dvfStatus = "Enabled";
trainingStatus = "Enabled";
inferenceStatus = "Enabled";
}
return [dvfStatus,trainingStatus,inferenceStatus];
}catch(err){
throw(err);
}
}
有人可以帮我吗?
您的主要问题是 fetchStatusDBs
中的状态变量未声明,因此 implicitly global。由于您的代码正在进行多个并发调用,这些调用在 await
暂停点处交错,因此它们相互影响 - 一个典型的竞争条件。要解决此问题,只需使用 let
或 var
.
const data=[[],['1'],['2'],['3']];
async function getStatusAll(data) {
console.log("In getStatusAll");
let statusPromiseArray = data.map(this.fetchStatusDBs, this);
return Promise.all(statusPromiseArray);
}
async function fetchStatusDBs(data) {
console.log("In fetchStatusDBs");
let dvfStatus, trainingStatus, inferenceStatus;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//fetch status in dvf_req_id for an dvf_req_id
if (data.length==0) {
console.log("1");
dvfStatus = await Promise.resolve("Disabled");
console.log("2");
trainingStatus = await Promise.resolve("Disabled");
console.log("3");
inferenceStatus = await Promise.resolve("Disabled");
} else {
console.log("4");
dvfStatus = await Promise.resolve("Enabled");
console.log("5");
trainingStatus = await Promise.resolve("Enabled");
console.log("6");
inferenceStatus = await Promise.resolve("Enabled");
}
return [dvfStatus, trainingStatus, inferenceStatus];
}
这将得到预期的结果(return 值)。为了从日志中获得预期的输出,您不能将 map
与异步函数一起使用,然后使用 Promise.all
等待所有承诺,但您需要按顺序进行调用:
async function getStatusAll(data) {
console.log("In getStatusAll");
const statusArray = [];
for (const value of data) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^
statusArray.push(await this.fetchStatusDBs(value));
// ^^^^^
}
return statusArray ;
}
你对async-await有几个误解
async function getStatusAll(data) {
console.log("In getStatusAll");
<del>try{</del>
let statusPromiseArray = data.map(async(value) => { // map is sync
result= await this.fetchStatusDBs(value); // global result
return result; // return-await anti-pattern
});
statusResolvedArray= await Promise.all(statusPromiseArray) // global
return statusResolvedArray; // return-await anti-pattern
<del>}catch(err){</del> // catch-throw anti-pattern
<del>throw(err);</del>
<del>}</del>
}
所有这些都可以写成-
function getStatusAll(data) {
return Promise.all(data.map(v => this.fetchStatusDBs(v)))
}
任何错误都会自动冒出来。无需catch
和重新throw
。这将在 并行 中执行所有提取。如果需要,您可以在 serial 中执行请求。这表明在 async
-
await
async function getStatusAll(data) {
const result = []
for (const value of data)
result.push(await this.fetchStatusDBs(value))
return result
}