了解Promise Javascript中的承诺

时间:2015-09-19 01:50:52

标签: javascript angularjs promise angular-promise

我已阅读:Promise - JavaScript | MDN我在这里查看了本书中有关承诺的部分:Eloquent Javascript以及其他Google搜索,但我似乎无法确定这是否是问题是因为我对Promises或图书馆的混合物的理解。我想要完成的是发出请求,检索响应,然后使用该响应发出另一个请求。我想我可以使用正常模式:

promiseObj.get('url')
.then(function(response){
    //do something with response
    var name = response.name;
    return name;
})
.then(function(name){
    //do something with name
}

但有些事情并没有正常运作。我试图使用两个不同的promise对象来发出请求。我必须使用podio API发出请求,检索信息然后使用AngularJS $ http promise。这是我的代码:

podio.request('get','/item/' + eventId).then(function(responseEvent) {
   ...   
   var imgId = responseEvent.img_id;
   ...
   return imgId;

}).then(function(imgId){
    console.log(imgId);

   var config = { responseType: 'arraybuffer'};
   $http.get('https://api.podio.com/file/' + imgId + '/raw',config)
   .then(function(response) {
        console.log('hi 2');
        var arr = new Uint8Array(response.data);
        var raw = String.fromCharCode.apply(null,arr);
        var b64 = btoa(raw);
        var dataURL = "data:image/jpeg;base64,"+b64;
        $scope.event.img.src = dataURL;
        },function(error){
           console.log(error);
        });
});

在我的第二个然后中,我可以在控制台中看到imgId,但之后没有任何事情发生。我可能会错过什么。

3 个答案:

答案 0 :(得分:1)

如果您想创建两个承诺,请尝试以下内容:

p1.get(function (response) {
  // Work with response here
  return response;
}).then(function (response) {
  return p2.get(response.urlMaybe);
}).then(function (response) {
  // Work on second response
});

大量假,但可能有所帮助。

答案 1 :(得分:1)

一个原因可能是您没有外部承诺的错误处理程序,因此如果在console.log之后抛出异常,则错误可能无法检测到。我建议您展平您的Promise链,以便处理所有错误:

podio.request('get','/item/' + eventId)
  .then(function(responseEvent) {
    ...   
    var imgId = responseEvent.img_id;
    ...
    return imgId;
  })
  .then(function(imgId){
    console.log(imgId);
    var config = { responseType: 'arraybuffer'};
    return $http.get('https://api.podio.com/file/' + imgId + '/raw',config);
  })
  .then(function(response) {
    console.log('hi 2');
    var arr = new Uint8Array(response.data);
    var raw = String.fromCharCode.apply(null,arr);
    var b64 = btoa(raw);
    var dataURL = "data:image/jpeg;base64,"+b64;
    $scope.event.img.src = dataURL;
  },function(error){
     console.log(error);
  });

答案 2 :(得分:1)

除了Adrian Lynch的正确答案之外,假设我们有一系列请求。每个请求都取决于所有先前请求的结果。

promiseFn().then(function(resp) {
    return Promise.all([resp, otherPromiseFn(resp)]);
}).then(function(vals) {
    var first  = vals[0];
    var second = vals[1];
    return Promise.all([first, second, thirdPromiseFn(first, second)]);
});

..依此类推,汇总价值观。重要的是,每次你有一个承诺返回函数调用你只需返回承诺,然后你打电话。请记住,您从传递给函数返回的所有内容都会自动包装为您要返回的值的承诺。