javascript - 将 forEach 与 $q 同步使用

标签 javascript arrays angularjs asynchronous

所以我遇到这样一种情况,我需要构建一个对象,然后将一些项目注入(inject)到该对象中,然后进行 API 调用并将 API 的响应注入(inject)到该对象中。这是一个复杂的对象,所以我们假设没问题,但无论如何,我认为我需要同步执行这 3 件事,使用 array.forEach 意味着它们异步运行。

我希望我的示例足够简单易懂,但基本上我做了 3 件事:

  • 创建一个空的类(class)/教室数组
  • 遍历类 ID 数组并为每个 Class 创建一个对象
  • 遍历Students 数组并将它们插入Class 对象中的students 数组
  • 遍历Options 数组并将它们放入Class 对象中的options 数组

最后,我为每个类(class)准备了一些看起来像这样的东西:

{
  class_id: "abc123",
  students: [{}, {}, {}],
  options: [{}, {}, {}]
}

最后,这是我的代码:

// Create Array of Class Objects
var classes = [];

function processArray(array, func) {
  return $q(function(resolve, reject) {
    array.forEach(function(item, index) {
      func(item);
      if (index === (array.length - 1)) resolve();
    })
  })
}

// Create Courier Objects
processArray(classIds, function(id) {
  classes.push({class_id: id, students: [], options: []});
}).then(function(response) {
  // Inject Students into each Class
  processArray(students, function(students) {
    _.find(classes, {'class_id': student.class_id}).students.push(student);
  }).then(function(response) {
    // Inject classOptions into each Class
    processArray(classOptions, function(classOption) {
      _.find(classes, {'class_id': classOption.class_id}).classOptions.push(classOption);
    }).then(function(response) {
      // Print the classes
      console.log(classes);
    })
  })
});

我已经创建了一个同步执行它的函数,但我想知道是否有人能想到一种更简洁、更有效的方法来执行上述操作。这看起来非常 hacky,如果我正确安排我的功能,也许我什至不需要同步执行。

最佳答案

使用返回数组的基于 Promise 的 API

processArray 函数返回解析为 null 的 promise 。

//WRONG
//Returns a promise that resolves to null
//
function processArray(array, func) {
  return $q(function(resolve, reject) {
    array.forEach(function(item, index) {
      func(item);
      if (index === (array.length - 1)) resolve();
    })
  })
}

要返回解析为数组的 promise ,请使用 $q.all

//RIGHT
//Returns a promise that resolves to an array
//
function processArray(array, func) {
    var promiseArray = [];
    array.forEach(function(item, index) {
        promiseArray.push($q.when(func(item));
    });
    return $q.all(promiseArray);
}

无论是 func(item) 返回一个值还是一个 promise,$q.when 都会返回一个 promise。

请注意 $q.all没有弹性的。它将解析为一组值,或者它将解析为第一个错误被拒绝。

processArray(array, func)
    .then( function onFulfilled(dataList) {
        //resolves with an array
        $scope.dataList = dataList;
    }).catch( function onRejected(firstError) {
        console.log(firstError);
    });

有关详细信息,请参阅 AngularJS $q Service API Reference .

关于javascript - 将 forEach 与 $q 同步使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36337960/

相关文章:

javascript - 使用 Angular.js 和 D3 绘制图表

arrays - 在 postgres jsonb 数组中查找对象的位置

java - 使用 FileInputStream/ObjectOutputStream 发送大文件

C++ 多维数组的可能性

javascript - Angularjs $http 404 调用 Web Api

javascript - 通过 Angular http 请求发布文件

javascript - 使用 AngularJS 在窗口调整大小时调整 div 大小

javascript - 向下滚动到 Javascript 进度条后加载它

javascript - AngularJs:我想在按钮单击时销毁模态弹出窗口中的内容

javascript - 使用 angularjs 使用 nganimate 进行前后导航