我正在尝试兑现诺言,但是似乎当我这样做时:
if (o.TotalCollectionSize - 20 <= index) {
var selectedserver = games.gameservers[Math.floor(Math.random() * games.gameservers.length)]
console.log(selectedserver)
resolve(selectedserver)
return;
}
承诺无法解决,但是,如果解决方案不在if语句的范围内,那么解决方案将起作用。
(o.TotalCollectionSize - 20 <= index)
这句话永远都是正确的,我需要它在到达这一点时停止,这就是为什么我要在这里解决它。
console.log(selectedserver)
可以正常工作,并向我显示需要解决的问题。我的问题是,一旦到达需要解决的地步,就不需要了。
getPing(game.placeId, 0).then(function (r) {
console.log(r)
res.end(JSON.stringify(r))
})
getPing是一个返回新promise的函数,(r)值就是要解析的值。如前所述,我的resolve()在if语句之外运行,我不确定为什么它在内部不起作用。我是新来的诺言,所以这可能是一个小问题。
编辑:这是需要看的人的全部功能,
var getPing = function (id,index) {
return new Promise(function (resolve, reject) {
options.agent = keepAliveAgent
index = index || 0;
var r = https.request(options, function (res) {
var data = []
res.on('data', function (d) {
data.push(d)
}).on('end', function () {
var buf = Buffer.concat(data)
var encodingheader = res.headers['content-encoding']
if (encodingheader == 'gzip') {
zlib.gunzip(buf, function (err, buffer) {
var o = JSON.parse(buffer.toString())
// o is what is returned
if (o.TotalCollectionSize - 20 <= index) {
console.log(o.TotalCollectionSize - 20, '<=', index)
var selectedserver = games.gameservers[Math.floor(Math.random() * games.gameservers.length)]
console.log(selectedserver)
resolve(selectedserver)
return;
}
if (index < o.TotalCollectionSize) {
index = index + 10;
console.log(index, o.TotalCollectionSize)
o.Collection.sort(function (a, b) {
return a.Ping > b.Ping
})
if (typeof (o.Collection[0]) != "undefined") {
var playerscapacity = o.Collection[0].PlayersCapacity.charAt(0)
if (playerscapacity != o.Collection[0].Capacity) {
games.gameservers.push(o.Collection[0])
}
}
getPing(id, index)
}
})
}
})
})
r.end()
//reject('end of here')
})
}
就像我提到的那样,所有这些代码都可以很好地工作,直到有时间解决承诺为止。
答案 0 :(得分:1)
我将试图回答这个问题,而实际上并不知道您的功能应该做什么或应该如何工作(因为您没有告诉我们),所以请耐心等待。
一个有保证的经验法则是new Promise
应尽量少用,并且在使用时应尽可能简单。它应该只包含您要承诺的非承诺异步功能,它们仅包含 ,其余逻辑应在根据您从中获得的承诺进行工作。它不应该是装载回调的烂摊子的巨大容器。
在您的情况下,您有两个异步操作:缓冲的HTTP请求和GZIP提取,因此让我们为它们创建单独的函数:
function requestBufferedData(options) {
return new Promise(function (resolve, reject) {
// TODO: Needs to reject() in situation where request fails or else
// this promise will never complete when there's an error
var r = https.request(options, function (res) {
var data = []
res.on('data', function (d) {
data.push(d);
}).on('end', function () {
resolve({
data: Buffer.concat(data),
encoding: res.headers['content-encoding'],
});
});
});
r.end();
});
}
function extractGzip(data) {
return new Promise(function (resolve, reject) {
zlib.gunzip(data, function (err, buffer) {
if (err) { reject(err); }
else { resolve(buffer); }
});
});
}
现在有了这些,我们可以更加轻松地呼吸。在查看了其余代码约10分钟之后,我仍然无法理解它的正面或反面,因此我将不得不遍历它。清楚的是,您有一个递归过程,该过程重试您的HTTP请求,直到找到所需的值为止,因此我们将继续:
function getPing(id, index) {
options.agent = keepAliveAgent;
return requestBufferedData(options)
.then(function (result) {
if (result.encoding !== 'gzip') {
throw new Error('Response is not gzip');
}
return extractGzip(result.data);
})
.then(JSON.parse)
.then(function (o) {
if (o.TotalCollectionSize - 20 <= index) {
console.log(o.TotalCollectionSize - 20, '<=', index)
var selectedserver = games.gameservers[Math.floor(Math.random() * games.gameservers.length)]
console.log(selectedserver)
return selectedServer;
}
if (index < o.TotalCollectionSize) {
var nextIndex = index + 10;
console.log(nextIndex, o.TotalCollectionSize)
o.Collection.sort(function (a, b) {
return a.Ping > b.Ping
});
if (typeof (o.Collection[0]) != "undefined") {
var playerscapacity = o.Collection[0].PlayersCapacity.charAt(0);
if (playerscapacity != o.Collection[0].Capacity) {
games.gameservers.push(o.Collection[0])
}
}
return getPing(id, nextIndex);
}
throw new Error("Didn't match either condition");
});
}
我相信这会在满足条件时正确地解决诺言,但是我无法对此进行测试,因此,如果您仍然对此有疑问,请告诉我。