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);
});