Angular2 - 变量在服务调用中使用时包含错误的数据

时间:2018-01-03 19:07:06

标签: javascript angular http typescript asynchronous

我在使用属于它的数据(例如usernamedescription等)映射我从服务器获取的每个blob时遇到问题。我想将数据与blob网址结合起来到一个对象,但obj in then()不包含正确的信息(可能是因为异步)

任何提示?

//Every object gets this in the data property (which is the last entry in the posts object)
Object { _id: "5a4511f44fc50b0011614cc3", username: "paikz", img: "0ecdede24b40ec16aaaeb2c5b3db6039151…", __v: 0, date: "2017-12-28T15:47:00.263Z", description: "My desc" }

getPostsImage(posts: Object) {
  this.postUrls = [];
  for (let key in posts) {
    var obj = posts[key];
    this.contentService.getPostsImage(obj['img'])
      .then(blob => {
        let urlCreator = window.URL;
        this.postUrls.push({
          url: this.sanitizer.bypassSecurityTrustUrl(urlCreator.createObjectURL(blob)),
          //obj here is the problem
          data: obj
        });
      })
      .catch(err => console.log(err));
  }
}

1 个答案:

答案 0 :(得分:0)

下面的代码段显示了如何解决问题的可能性。线索是将对象绑定到匿名函数,以便在返回blob并解析promise时立即将其作为函数参数访问:



// for simulating the input
const fakePosts = {
  key1: {
    attr: 'value1',
    img: '...'
  },
  key2: {
    attr: 'value2',
    img: '...'
  }
};

// your postUrls
const postUrls = [];

// fake service function for simulating the async call
function getServicePostsImage(img: string) {
    const delayed = new Promise((resolve) => {
        setTimeout(() => {
            resolve('fakeblob');
        }, Math.floor(Math.random() * 300));
    });

  return delayed;
}

// getPostsImage
function getPostsImage(posts: Object) {
  for (let key in posts) {
    const obj = posts[key];

    getServicePostsImage(obj['img'])
      .then(((obj, blob) => {
        postUrls.push({
          url: blob,
          data: obj
        });
        
        // order might vary due to async calls kicking in in undefined order, but as long as this is no problem for you..
        console.log(postUrls);
      }).bind(this, obj)) // <== binding the object allows you to access it inside the function!
      .catch(err => console.log(err));
  }
}

// run it
getPostsImage(fakePosts);
&#13;
&#13;
&#13;