在javascript对象中推送到数组

在javascript对象中推送到数组,javascript,arrays,angularjs,javascript-objects,Javascript,Arrays,Angularjs,Javascript Objects,函数v1执行w/o error,控制台日志显示使用响应数据填充的预期阵列。但是,我试图通过在nysQueryReturn中返回2个数组作为对象来简化以后的工作: 函数v2执行时也没有错误,但控制台日志显示 nysQueryReturn {sldlBills: Array(0), slduBills: Array(0)} 函数v2:空数组: function getBillData() { return getBills(). then(function(response) { /

函数v1执行w/o error,控制台日志显示使用响应数据填充的预期阵列。但是,我试图通过在nysQueryReturn中返回2个数组作为对象来简化以后的工作:

函数v2执行时也没有错误,但控制台日志显示 nysQueryReturn {sldlBills: Array(0), slduBills: Array(0)} 函数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的和的例子,但是我不知道如何重新使用这些答案来适应我的数组对象场景。任何关于我所缺少的东西的想法/建议/解释都将受到热烈欢迎

谢谢你抽出时间

编辑:

k、 我发现了,这似乎表明我做得对。再看一看,ChromeDevTools控制台报告这两个阵列是空的,但展开后它们包含预期的信息。尽管如此,我仍然无法实际访问带有nysQueryReturn.sldlBills[0]的数组元素。basePrintNo不获取TypeError:无法读取undefined的属性'basePrintNo',并且我一辈子都无法找出原因


我没有得到什么?

我假设您知道以及如何正确使用它们。我还假设你知道和。这些都不是必需的,它们只是让事情变得更漂亮一点。您可以将下面示例中的所有箭头函数替换为普通函数,将所有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,承诺是工作者,而把getBillData称为客户的代码。使用getBillData的v2,您可以

找到了所有的账单。 创建了nysQueryReturn框 雇佣了一些工人,告诉他们该怎么做。 把盒子给你的顾客。 不幸的是,您没有等到您的员工完成他们的工作后,才将箱子交给客户。不用说,你的客户很困惑,只是假装他们得到了他们想要的

通过新的实现,您可以

找到了所有的账单。 创建了nysQueryReturn框 雇佣了一些工人,告诉他们该怎么做。 等待你的工人把他们发现的东西给你。 把盒子给你的顾客。 通过维护工作人员列表,然后等待所有工作人员告诉您他们已经完成并将结果添加到nysQueryReturn框中,等待工作人员完成。完成所有操作后,您将向客户提供所有结果。然后=>nysQueryReturn

请记住,每次使用Promise时,只要有.then方法,您就是在正常程序流之外执行某些操作。JS不会等待该流完成后再继续其原始流。从图片上看,这看起来像:

___________                     ____________                                ____________
|  Flow 1 |                     |  Flow 2  |                                |  Flow 3  |
-----------                     ------------                                ------------

billData.forEach(/* ... */);
console.log(/*...*/);
return nysQueryReturn;
                                nysQueryReturn.sldlBills.push(/*...*/);
                                                                            nysQueryReturn.slduBills.push(/*...*/)

要等待新流完成,您必须通过向传递回调来显式地等待它。然后。

承诺是异步函数,因此不要逐行运行。我建议您阅读,以了解承诺是如何工作的。 您可以尝试以下代码:使用map返回承诺,然后使用Promise.all等待全部完成

function getBillData() {
    return getBills()
    .then(function (response) {
        var billData = response;
        var nysQueryReturn = {
            sldlBills: [],
            slduBills: []
        };

        prs = billData.map(function (p) {
            return nysBillQuery(p.gsx$sessionyear.$t, p.gsx$assemblynum.$t)
                .then(function (res) {
                    nysQueryReturn.sldlBills.push(res);
                    return nysBillQuery(p.gsx$sessionyear.$t, p.gsx$senatenum.$t);
                })
                .then(function (res) {
                    nysQueryReturn.slduBills.push(res);
                });
            });

        return Promise.all(prs).then(function () {
            return nysQueryReturn
        });

    });
} // end of getBillData()

问题在于如何处理异步代码。我建议研究async.js。我将在下面添加一个更好的解释。很抱歉,async.js不是合适的工具。然而,我确实补充了一个解释。如果解释有帮助,请告诉我。同样感谢@HereticMonkey的dupe链接;这个周末将需要大量的异步阅读,我显然没有我想象的那么理解;我和妻子都从你的客户那里得到了一个笑声,他们很困惑,只是假装他们得到了他们想要的。让别人笑一直是我的第二个目标:很高兴你喜欢。
function getBillData() {
    return getBills()
    .then(function (response) {
        var billData = response;
        var nysQueryReturn = {
            sldlBills: [],
            slduBills: []
        };

        prs = billData.map(function (p) {
            return nysBillQuery(p.gsx$sessionyear.$t, p.gsx$assemblynum.$t)
                .then(function (res) {
                    nysQueryReturn.sldlBills.push(res);
                    return nysBillQuery(p.gsx$sessionyear.$t, p.gsx$senatenum.$t);
                })
                .then(function (res) {
                    nysQueryReturn.slduBills.push(res);
                });
            });

        return Promise.all(prs).then(function () {
            return nysQueryReturn
        });

    });
} // end of getBillData()