包含promises的对象数组在for循环中搞乱

时间:2016-03-10 08:25:00

标签: javascript

我有一个带有dogecoin地址的对象数组:

var wallets = [
        { address: 'DT2rmMrutwzdZ8EXwzj4QFdcL6DtvGGkci'}, 
        { address: 'DMoonjyH1aHLZc1kksmikBUhjXromn1ZN4'}
    ];

我还有一个简单的http请求函数:

function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);
    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      }
      else {
        reject(Error(req.statusText));
      }
    };
    req.onerror = function() {
      reject(Error("Network Error"));
    };
    req.send();
  });
}

我尝试使用for循环向包含promise / api响应的数组wallets中的每个对象添加一个新属性:

for (i in wallets){
    var balance = get('https://dogechain.info/api/v1/address/balance/'+wallets[i].address)
    .then(
        function(response){
            wallets[i].balance = response;
        },
        function(error) {
            wallets[i].balance = error;
        }
    );
};

console.log(wallets);

但是在每次迭代中,当promise得到解决时,for循环结束,将响应分配给最后一个对象。

我想要的是这样的数组:

[
{ address: 'DT2rmMrutwzdZ8EXwzj4QFdcL6DtvGGkci', balance: -balance from api response-},
{ address: 'DMoonjyH1aHLZc1kksmikBUhjXromn1ZN4', balance: -balance from api response-}
]

1 个答案:

答案 0 :(得分:1)

拳头观察是返回的值是字符串而不是对象。

resolve(req.response);

更改为

resolve(JSON.parse(req.response));

如果我理解你想要用所有Promises响应填充数组。

   var wallets = [
      { address: 'DT2rmMrutwzdZ8EXwzj4QFdcL6DtvGGkci'},
      { address: 'DMoonjyH1aHLZc1kksmikBUhjXromn1ZN4'}
    ];


    listPromises = wallets.map(function (wallet){
      var balance = get('https://dogechain.info/api/v1/address/balance/'+wallet.address)
        .then(function(response){
            return {
              address: wallet.address,
              balance: response.balance
            };
          },
          function(error) {
            return {
              address: wallet.address,
              balance: error
            }
          }
        );
      return balance
    });


    Promise.all(listPromises)
      .then(function(responseWallets){
        console.log(responseWallets);
        // add your script to continue

      });

    function get(url) {
      return new Promise(function(resolve, reject) {
        var req = new XMLHttpRequest();
        req.open('GET', url);
        req.onload = function() {
          if (req.status == 200) {
            resolve(JSON.parse(req.response));
          }
          else {
            reject(Error(req.statusText));
          }
        };
        req.onerror = function() {
          reject(Error("Network Error"));
        };
        req.send();
      });
    }

我希望它有所帮助。享受!

我在@Bergi建议之后简化了脚本。