This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(6个答案)
2年前关闭。
函数v1执行w / o错误,并且控制台日志显示了填充有响应数据的预期数组。但是,我试图通过将nysQueryReturn中的2个数组作为对象返回来简化生活。
功能v2也可以无错误执行,但控制台日志显示
函数v2:空数组:(
我在stackoverflow上找到了"array of arrays"和"array of objects"的几个示例,但是我看不到如何重新调整这些答案的大小以适合我的“数组对象”方案。我所缺少的任何想法/指针/解释都将受到热烈欢迎。
感谢您的时间。
编辑:
k,我发现this question & answer,这似乎表明我“做对了”。换个角度看,Chrome Dev Tools控制台报告这两个阵列为“空”,但展开时它们包含预期的信息。尽管如此,我实际上无法在不获取
我没有得到什么?
您没有看到期望的结果,因为您没有等待结果加载。实际上,如果您设置了超时并在以后的某个时间检查结果,您将看到阵列已填充。
让我们将
找到所有的账单。
创建了
雇用了一些工人,并告诉他们该怎么做。
把盒子交给你的顾客。
不幸的是,您没有等到您的工人完成工作,然后再将盒子交给客户。不用说,您的客户很困惑,只是假装他们得到了他们想要的东西。
通过新的实施,您可以
找到所有的账单。
创建了
雇用了一些工人,并告诉他们该怎么做。
等待您的工人给您他们发现的东西。
把盒子交给你的顾客。
您可以通过维护
请记住,每次使用
要等待新流程完成,您必须通过将回调传递给
(6个答案)
2年前关闭。
函数v1执行w / o错误,并且控制台日志显示了填充有响应数据的预期数组。但是,我试图通过将nysQueryReturn中的2个数组作为对象返回来简化生活。
功能v2也可以无错误执行,但控制台日志显示
nysQueryReturn {sldlBills: Array(0), slduBills: Array(0)}...empty arrays.
Function v1: works as expected
function getBillData() {
return getBills().
then(function(response) {
// save retrieved bill numbers
var billData = response;
var nysQueryReturn = [];
// get NY State Leg data for each bill number
billData.forEach(function(p) {
// Assembly bill
nysBillQuery(p.gsx$sessionyear.$t, p.gsx$assemblynum.$t).
then(function(response){
nysQueryReturn.push(response);
});
// Senate bill
nysBillQuery(p.gsx$sessionyear.$t, p.gsx$senatenum.$t).
then(function(response){
nysQueryReturn.push(response);
});
});
console.log('nysQueryReturn', nysQueryReturn);
return nysQueryReturn;
});
} // end of getBillData()
函数v2:空数组:(
function getBillData() {
return getBills().
then(function(response) {
// save retrieved bill numbers
var billData = response;
var nysQueryReturn = {
sldlBills: [],
slduBills: []
};
// get NY State Leg data for each bill number
billData.forEach(function(p) {
// Assembly bill
nysBillQuery(p.gsx$sessionyear.$t, p.gsx$assemblynum.$t).
then(function(response){
nysQueryReturn.sldlBills.push(response);
});
// Senate bill
nysBillQuery(p.gsx$sessionyear.$t, p.gsx$senatenum.$t).
then(function(response){
nysQueryReturn.slduBills.push(response);
});
});
console.log('nysQueryReturn', nysQueryReturn);
return nysQueryReturn;
});
} // end of getBillData()
我在stackoverflow上找到了"array of arrays"和"array of objects"的几个示例,但是我看不到如何重新调整这些答案的大小以适合我的“数组对象”方案。我所缺少的任何想法/指针/解释都将受到热烈欢迎。
感谢您的时间。
编辑:
k,我发现this question & answer,这似乎表明我“做对了”。换个角度看,Chrome Dev Tools控制台报告这两个阵列为“空”,但展开时它们包含预期的信息。尽管如此,我实际上无法在不获取
nysQueryReturn.sldlBills[0].basePrintNo
的情况下访问带有TypeError: Cannot read property 'basePrintNo' of undefined
的数组元素,并且我无法终生弄清楚为什么。我没有得到什么?
最佳答案
我假设您了解arrow functions以及如何正确使用它们。我还将假设您了解let
和const
。这些都不是必需的,它们只是使事情变得更漂亮。您可以将所有箭头功能(在下面的示例中)替换为普通功能,并将所有let
和const
声明替换为var
声明。
您的最终结果应类似于以下内容:
function getBillData() {
return getBills().then((billData) => {
const nysQueryReturn = {
sldlBills: [],
slduBills: []
};
// This should look familiar, it returns a Promise. This
// Promise first loads the Assembly bill then adds the result
// to the appropriate array in nysQueryReturn object.
const loadAssemblyBill = (bill) => {
return nysBillQuery(bill.gsx$sessionyear.$t, bill.gsx$assemblynum.$t).then((sldlBill) => {
nysQueryReturn.sldlBills.push(sldlBill);
});
};
// This should look familiar, it returns a Promise. This
// Promise first loads the Senate bill then adds the result to
// the appropriate array in nysQueryReturn object.
const loadSenateBill = (bill) => {
return nysBillQuery(bill.gsx$sessionyear.$t, bill.gsx$senatenum.$t).then((slduBill) => {
nysQueryReturn.slduBills.push(slduBill);
});
};
// First exciting thing: Let's map each bill to a 2 workers
// that will load the important information that we will add to
// nysQueryReturn.
const workers = [];
billData.forEach((bill) => {
workers.push(loadAssemblyBill(bill));
workers.push(loadSenateBill(bill));
});
// Return a Promise that will wait for all the workers to
// finish.
return Promise.all(workers).then(() => nysQueryReturn);
});
}
您没有看到期望的结果,因为您没有等待结果加载。实际上,如果您设置了超时并在以后的某个时间检查结果,您将看到阵列已填充。
让我们将
nysQueryReturn
视为一个包含所有sldlBills
和slduBills
,作为工作人员的Promises和作为客户的调用getBillData()
的代码的框。使用getBillData()
的v2,您找到所有的账单。
创建了
nysQueryReturn
框雇用了一些工人,并告诉他们该怎么做。
把盒子交给你的顾客。
不幸的是,您没有等到您的工人完成工作,然后再将盒子交给客户。不用说,您的客户很困惑,只是假装他们得到了他们想要的东西。
通过新的实施,您可以
找到所有的账单。
创建了
nysQueryReturn
框雇用了一些工人,并告诉他们该怎么做。
等待您的工人给您他们发现的东西。
把盒子交给你的顾客。
您可以通过维护
workers
列表来等待工作人员完成工作,然后等待他们的all()
(Promise.all()
)告诉您他们已经完成工作并将其结果添加到nysQueryReturn
框中。完成所有步骤后,即可将所有结果提供给客户(.then(() => nysQueryReturn)
)。请记住,每次使用
Promise
(具有.then()
方法的任何东西)时,您都在执行普通程序流程之外的内容。 JS将不等待该流程完成再继续其原始流程。从图片上看,这看起来像:___________ ____________ ____________
| Flow 1 | | Flow 2 | | Flow 3 |
----------- ------------ ------------
billData.forEach(/* ... */);
console.log(/*...*/);
return nysQueryReturn;
nysQueryReturn.sldlBills.push(/*...*/);
nysQueryReturn.slduBills.push(/*...*/)
要等待新流程完成,您必须通过将回调传递给
.then()
来显式等待它。09-25 21:14