Javascript 信誓旦旦

Javascript 信誓旦旦,javascript,asynchronous,promise,Javascript,Asynchronous,Promise,我所处的场景是,我必须按顺序从服务器获取数据,我希望在承诺的帮助下实现这一点。这就是我迄今为止所尝试的: function getDataFromServer() { return new Promise(function(resolve, reject) { var result = []; (function fetchData(nextPageToken) { server.getData(nextPageToken).then(function(res

我所处的场景是,我必须按顺序从服务器获取数据,我希望在承诺的帮助下实现这一点。这就是我迄今为止所尝试的:

function getDataFromServer() {
  return new Promise(function(resolve, reject) {
    var result = [];

    (function fetchData(nextPageToken) {

      server.getData(nextPageToken).then(function(response) {
        result.push(response.data);
        if (response.nextPageToken) {
          fetchData(response.nextPageToken);
        } else {
          resolve(result);
        }
      });

    })(null);

  });
}

getDataFromServer().then(function(result) {
  console.log(result);
});

第一次提取成功,但对
server.getData()
的后续调用不会运行。我认为这与第一个
然后()
没有实现有关。如何缓解此问题?

因为then语句没有传递处理错误情况的函数,所以向服务器请求数据的请求可能会以静默方式失败,在这种情况下,getDataFromServer返回的承诺将永远无法完成

要解决此问题,请将第二个函数作为参数传递给then,如下所示:

function getDataFromServer() {
  return new Promise(function(resolve, reject) {
    var result = [];

    (function fetchData(nextPageToken) {

      server.getData(nextPageToken).then(function(response) {
        result.push(response.data);
        if (response.nextPageToken) {
          fetchData(response.nextPageToken);
        } else {
          resolve(result);
        }
      }).catch(function(error) {
        //Note: Calling console.log here just to make it easy to confirm this
        //was the problem.  You may wish to remove later.
        console.log("Error occurred while retrieving data from server: " + error);
        reject(error);
      });

    })(null);

  });
}

Nimrand回答了您的问题(缺少
catch
),但这里是您的代码,没有:

正如您所看到的,递归非常适用于承诺

var控制台={log:function(msg){div.innerHTML+=“”+msg+“

”;}; 风险值响应=[ {数据:1001,下一个GetOken:1}, {数据:1002,nextPageToken:2}, {数据:1003,nextPageToken:3}, {数据:1004,nextPageToken:4}, {数据:1005,下一个GetOken:0}, ]; 变量服务器={ getData:函数(令牌){ 返回新承诺(函数(resolve){resolve(响应[token]);}); } }; 函数getDataFromServer(){ var结果=[]; 函数fetchData(nextPageToken){ 返回server.getData(nextPageToken).then(函数(响应){ 结果.推送(响应.数据); if(response.nextPageToken){ 返回fetchData(response.nextpGetOken); }否则{ 返回结果; } }); } 返回抓取数据(0); } getDataFromServer().then(函数(结果){ 控制台日志(结果); }) .catch(函数(e){console.log(e);})
so,console.log(结果);没有打电话/没有打印任何东西?@Joel完全正确。如果我登录到
getData().then()
,我将只得到第一部分的响应,而不是后续部分的响应。代码看起来应该可以工作。尝试在对“then”的调用中添加第二个函数来处理错误条件(至少现在记录错误)。我怀疑对server.getData的第二次调用正在悄无声息地失败。无论如何,您可能需要处理这些类型的错误。第一个“response.nextpGetOken”是什么?可能是0吗?在这种情况下,它会立即停止?(但这意味着承诺已经解决,而你说的不是);我在这里尝试了类似的代码,效果很好,所以问题可能出在服务器上side@Nimrand它确实失败了:)还不习惯抓住所有的承诺!非常感谢。最好完全避免这种情况!我考虑过重构代码以避免这种延迟承诺构造,但由于其递归性和调用server.getData的次数是不确定的,因此我看不到解决方法。但是,我不熟悉JavaScript中的承诺(尽管我在其他语言中使用过),因此如果您知道解决此问题的方法,请告诉我。
reject(error)
是正确的,但我会在记录之前让错误冒泡出来。i、 e.
getDataFromServer().then(result=>console.log(result)).catch(e=>console.error(e))-始终返回或终止带有catch的链,这是我使用的规则。这一点很好。在这里使用catch稍微安全一些。不同之处在于,即使传递给
然后
的函数中发生异常,您也会捕获异常,尽管该函数中没有任何东西会因异常而失败。@Nimrand:Recursion FTW!参见jib的回答。因此,当函数
f
传递到
时,那么
恰好返回一个承诺
a
,那么
返回的承诺是否也等待
a
完成?通常,
返回的承诺会在
f
完成后立即完成,这意味着此代码不一定有效。这太棒了。谢谢你,jib!喜欢承诺越来越多。:)是的,当一个承诺被解决为另一个未决的承诺时,第一个承诺仍然未决,直到第二个承诺得到解决才得以履行。在本例中,使用中的术语,第一个承诺已解决且待定,但尚未实现。谢谢。它在强类型语言(如Scala)中的工作方式有点不同,所以一开始我并不直观。但是,这是有道理的。
function getDataFromServer() {
  var result = [];

  function fetchData(nextPageToken) {
    return server.getData(nextPageToken).then(function(response) {
      result.push(response.data);
      if (response.nextPageToken) {
        return fetchData(response.nextPageToken);
      } else {
        return result;
      }
    });
  }
  return fetchData(null);
}

getDataFromServer().then(function(result) {
  console.log(result);
})
.catch(function(e) {
  console.error(e);
});