我正在访问API Trello,但我遇到了以下问题:
Trello访问信息,获取每个现有行的id,代码如下:
var x;
var numberCardsByList = [];
trello.get("/1/boards/[idBoard]/lists/all", function(err, data) {
if (err) throw err;
console.log("Number of list: " + data.length);
for(var i=0; i<data.length; i++){
x = data[i];
findNumberCards(x);
}
});
正如你所看到的,在获得大小之后,我将所有这些队列带走,在循环内,将每一行附加到变量x中并调用一个旨在获取排队卡数的函数。卡号的代码如下:
function findNumberCards(x){
trello.get("/1/lists/"+x.id+"/cards", function(err, dados){
if(err) throw err;
console.log("Name List: " + x.name + " have " + dados.length + " cards");
numberCardsByList[x.name] = dados.length;
});
}
在那之前可以,但是当我在Trello中搜索结束后尝试访问向量numberCardsByList
时,它返回undefined:
var x;
var numberCardsByList = [];
trello.get("/1/boards/[idBoard]/lists/all", function(err, data) {
if (err) throw err;
console.log("Quantidade de Filas: " + data.length);
for(var i=0; i<data.length; i++){
x = data[i];
findNumberCards(x);
}
});
console.log(numberCardsByList);
我知道这是因为异步,但无法解决。
答案 0 :(得分:0)
您面临的问题以前已经解决了很多次。如果您想了解更多信息,请搜索关键字&#34; Promise&#34; 。如果您熟悉jQuery,请尝试查找:$.whenAll
,$.ajax().done
,$.ajax().always
等。
如果你想自己想出一个轻量级的解决方案,这里有一个指针:
当您到达console.log(numberCardsByList)
时,findNumberCards
触发的请求尚未完成,Array
为空。您需要确保知道所有findNumberCards
请求何时完成,然后记录它们。或者,您可以在每次完成其中一个时记录。
大致有两种方法:
numberCardsByList
对象并在添加项目时调用函数(您不知道是否添加了异步或同步)我建议采用第一种方法。查看此示例代码和注释:
var numberCardsByList = {};
// This array will store the url for every open request
var openRequests = [];
var removeRequest = function(url) {
var index = openRequests.indexOf(url);
if (index === -1) return;
// Remove url from array
openRequests = openRequests
.slice(0, index)
.concat(openRequests
.slice(index + 1));
};
// This will be called whenever one request completes
var onComplete = function(url) {
removeRequest(url);
// When all have completed, we can call our callback
if (openRequests.length === 0) {
onAllComplete();
}
});
// This will be called when there are no open requests left
var onAllComplete = function(data) {
console.log(numberCardsByList);
}
trello.get("/1/boards/[idBoard]/lists/all", function(err, data) {
if (err) throw err;
console.log("Number of list: " + data.length);
for (var i = 0; i < data.length; i++) {
x = data[i];
findNumberCards(x);
}
});
function findNumberCards(x) {
var url = "/1/lists/" + x.id + "/cards";
// Before we make the request, we register it:
openRequests.push(url);
trello.get(url, function(err, dados) {
numberCardsByList[x.name] = dados.length;
// When it is completed, we call onComplete
onComplete(url);
});
};
&#13;
请注意,此onAllComplete
并非100%安全:如果请求在下一个请求启动之前完成,则可能会多次调用它。
<强>结论强>
如果可以,我会使用库来处理承诺。如果你想尝试自己构建一些东西,你可以尝试跟踪请求并在它们全部完成后执行回调。
答案 1 :(得分:0)
请记住,我的上述代码很可能不适合您,因为我不知道您的代码中发生了什么,所以这是一个示例/解释如何处理您的问题。
由于您不熟悉异步操作,我会假设您没有先前的承诺知识,因此会给您一个不太理想的解决方案 - 但是承诺会更好,您应该彻底学习它们。
您需要在异步代码的结果中执行序列过程。
首先,您将为第二个操作创建一个函数,例如:
function numberCardsByList (param1,param2){.....}
然后,您将更改fineNumberCards以接受回调:
function findNumberCards(x, callback){
trello.get("/1/lists/"+x.id+"/cards", function(err, dados){
if(err) throw err;
console.log("Name List: " + x.name + " have " + dados.length + " cards");
numberCardsByList[x.name] = dados.length;
});
// pass in any params you need.
callback();
}
然后您将新创建的函数numberCardsByList
传递给findNumberCards
或任何您想要的地方。
trello.get(“/ 1 / boards / [idBoard] / lists / all”,function(err,data){
if(err)throw err;
console.log(“列表数:”+ data.length);
for(var i=0; i<data.length; i++){
x = data[i];
// and here we are calling findNumberCards and passing in the callback..
findNumberCards(x, numberCardsByList);
}
});
通常你将如何处理异步操作,你将为下一个要执行的操作传递一个回调函数。
<强>更新强>
这里有一个例子,说明如何用另一个场景来完成这一点,只是为了证明这一点。
我们从获取用户开始
service.getUser(userName, function(err,user){
if(user) {
// we get user picture passing getPictureSize as callback
getUserPicture(user.picture, getPictureSize)
}
})
我们得到pictureURL
function getUserPicture(picName, cb){
service.getPictureURL(picName, function(err, pictureURL){
if(pictureURL) {
// we then call the callback - the next async operation we want.
cb(pictureURL);
}
});
}
我们得到图片大小 - 这是最后一次操作
function getPictureSize(pictureURL){
service.getPictureSize(pictureURL, function(err, pictureSize){
$('.picName').attr('src', picName);
$('.picName').width(pictureSize.width);
$('.picName').height(pictureSize.height);
});
}
我希望稍微澄清一下。