简体   繁体   English

循环内异步调用

[英]Async call inside loop

I have following code: 我有以下代码:

$scope.getEntriesBySpace = function(space, entryIds){
        var entriesHolder = [],
            errors = [];

        if(entryIds && entryIds.length > 0){
            angular.forEach(entryIds, function(entryId){
                space.cf_space.getEntry(entryId.trim()).catch(function(error) {
                    console.log('Could not find entry using access token, Error', error);
                    return error;
                }).then(function(response) {
                    if(response){
                        entriesHolder.push(data);
                    }else{
                        errors.push({"id": entryId, "message": "Entry not found"});
                    }
                });
            });
        }
    };

i call it like that: 我称之为:

$scope.getEntriesBySpace(sourceSpace, entries);

I want to store every response after each call finished inside the loop and return as array of responses or errors. 我想在每个调用在循环内完成后存储每个响应,并作为响应或错误的数组返回。

Any help is appreciated. 任何帮助表示赞赏。

Method getEntry returns promise. 方法getEntry返回promise。

For ref see this library: https://github.com/contentful/contentful-management.js 有关参考,请参阅此库: https//github.com/contentful/contentful-management.js

Thanks 谢谢

You can use the lib async for that: https://github.com/caolan/async 您可以使用lib async: https//github.com/caolan/async

$scope.getEntriesBySpace = function(space, entryIds){
    var entriesHolder = [],
        errors = [];

    var fn = function(entryId, callback){
          space.cf_space.getEntry(entryId.trim())
              .catch(function(error) {
                   console.log('Could not find entry using access token, Error', error);
                   /// just get out of here
                  return callback({"message": "Entry not found"});
              }).then(function(response) {
                  if(response){
                      // good response
                      return callback(null, data);
                  }else{
                      // bad response
                      return callback({"id": entryId, "message": "Entry not found"});
                  }
              });
    });

    if(entryIds && entryIds.length > 0){
        async.map(entryIds, fn, function(err, results){
            if(err) {
                // deal with the errors
            }
            // your array
            console.log(results);
        });
    }

});

getEntriesBySpace cannot return an array of the items you want (asyncronicity). getEntriesBySpace无法返回所需项目的数组(asyncronicity)。 It can, however, return a promise that references an array of the desired items. 但是,它可以返回一个引用所需项目数组的promise。 Or, since you want errors too, an object that contains both the good results and the errors. 或者,既然您也想要错误,那么该对象既包含好结果又包含错误。

$scope.getEntriesBySpace = function(space, entryIds){

    if(entryIds instanceof Array){
        return Promise.all(entryIds.map(function(entryId){
            return space.cf_space.getEntry(entryId.trim()).catch(function(error) {
                console.log('Could not find entry using access token, Error', error);
                throw error;
            });
       })).then(function(responses) {
           var resultAndErrors = {result: [], errors: []};
           responses.forEach(function(response) {
               if (!response) {
                   resultAndErrors.errors.push(({"id": entryId, "message": "Entry not found"});
               }
               else {
                   resultAndErrors.result.push(response);
               }
           });
           return resultAndErrors;
       });
    }
    else {
        return Promise.resolve([]);
    }
};

So there's two ways of doing this. 所以有两种方法可以做到这一点。 When you have promises, you also generally page a Promise.all method which is part of the promise implementations. 当你有承诺时,你通常也会寻找一个Promise.all方法,它是promise实现的一部分。 In Angular, you'd do $q.all. 在Angular中,你会做$ q.all。

So then you can do something like: 那么你可以这样做:

$q.all(entryIds.map(function(entryId){ return space.cf_space.getEntry(entryId.trim()) })) .then(function(entries){ console.log(entries) })

However, it seems like you're using the contentful SDK, where you also have a getEntries method which has query parameters which allow you to get more than one entry at once in one request. 但是,您似乎正在使用内容丰富的SDK,其中您还有一个getEntries方法,该方法具有查询参数 ,允许您在一个请求中一次获得多个条目。 This would be the most desirable thing because it would be much faster. 这将是最令人向往的事情,因为它会更快。

space.cf_space.getEntries({'sys.id[in]': entryIds.join(',')}) .then(function(entries){ console.log(entries) })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM