Javascript 将API调用forEach循环转换为Promise

Javascript 将API调用forEach循环转换为Promise,javascript,promise,Javascript,Promise,我有一个带有forEach循环的API调用,我需要在调用另一个函数之前完成该调用。看起来是这样的: var getTypes = function() { var stations = []; stationservice.getCount('/stations') .then(succCB, errorCB); function succCB(data) { data.data.forEach(func

我有一个带有
forEach
循环的API调用,我需要在调用另一个函数之前完成该调用。看起来是这样的:

var getTypes = function() {
        var stations = [];

        stationservice.getCount('/stations')
        .then(succCB, errorCB);

        function succCB(data) {
            data.data.forEach(function(station) {
                stations.push({
                    id: station._id,
                })
            })
        };
        // This should only be called once the forEach Loop is done
        processStations(stations);
}

我找不到一个可以理解的例子来说明如何确保循环完成后调用
processStations()
。我如何才能为此做出承诺,从而实现我想要实现的目标

一旦您使用承诺,您就必须链接依赖于该承诺的所有内容(或者使用
wait
async
,如果您的环境支持它):

如果
getTypes
返回的内容取决于
stationservice.getCount
,则至少应该从
getTypes
返回承诺链

您可能希望使用
map
而不是
forEach
,因为这是您实际要做的:

function getTypes() {
  return stationservice.getCount('/stations')
    .then(function(data) {
      return data.data.map(function(station) {
        return {
          id: station._id,
        };
      })
    })
    .then(processStations);
}
如果你想要一个“现代代码”的答案

这等于

var getTypes = function getTypes() {
    return stationservice.getCount('/stations').then(function (data) {
        return data.data.map(function (_ref) {
            return { id: _ref._id };
        });
    }).then(processStations);
};
但是,由于映射根本不是异步的

const getTypes = () => stationservice.getCount('/stations').then(data => processStations(data.data.map(({_id: id}) =>({id}))));
很好,而且是在前现代浏览器中

var getTypes = function getTypes() {
    return stationservice.getCount('/stations').then(function (data) {
        return processStations(data.data.map(function (_ref) {
            return { id: _ref._id };
        }));
    });
};
使用异步库

async.forEach(data.data, function (item, callback){ 
    stations.push({
        id: item._id,
    })
    callback(); 
}, function(err) {
    processStations(stations);
});

将需要执行的代码放在forEach循环之后,就放在forEach循环之后,但要放在
succb
内部-否则异步会让你头疼。。。注意:使用数组映射函数,而不是将新数组作为processStations的参数。。。。e、 g.
processStations(data.data.map(station=>({id:sation._id}))
@JaromandaX谢谢,这是一个糟糕的例子。我仍然对如何使用承诺来实现这一点感兴趣,因为我有其他的例子表明这是行不通的。
如何使用承诺来实现这一点
-你使用的是承诺(那么就是赠品)坏例子-嗯,每种情况都会产生不同的答案-最好阅读一些承诺文档:p应该是
item.push
(id:item.u id)
对吗?使用带有承诺的async.js(问题中已经有承诺)是一种破坏承诺的方法,使用承诺或异步库将导致相同的问题,两者都是异步的。您的
函数(err){processStations(stations);}
将与使用
相同。然后使用带有承诺的
var getTypes = function getTypes() {
    return stationservice.getCount('/stations').then(function (data) {
        return processStations(data.data.map(function (_ref) {
            return { id: _ref._id };
        }));
    });
};
async.forEach(data.data, function (item, callback){ 
    stations.push({
        id: item._id,
    })
    callback(); 
}, function(err) {
    processStations(stations);
});