繁体   English   中英

返回时能否兑现承诺?

[英]Is it possible to resolve a promise while returning?

我正在尝试兑现诺言,但是当我这样做时:

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

就像我提到的那样,所有这些代码都可以完美工作,直到有时间解决承诺。

我将尝试在不真正知道您的功能应该做什么或应该如何工作的情况下回答这个问题(因为您没有告诉我们),所以请耐心等待。

有保证的经验法则是, new Promise使用new Promise ,并且在使用时应尽可能简单。 它应包含您要承诺的非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");
         });
}

我相信这会在条件满足时正确解决诺言,但是我无法对此进行测试,因此,如果您仍然遇到此问题,请告诉我。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM