Можно ли выполнить обещание при возвращении? - PullRequest
0 голосов
/ 08 июня 2019

Я пытаюсь выполнить обещание, однако, кажется, что когда я делаю это:

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 - это функция, которая возвращает новое обещание, значение (r) будет тем, что разрешено. Как упоминалось ранее, мой метод resolv () работает вне оператора 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')
})
}

Как я уже говорил, весь этот код прекрасно работает, пока не придет время выполнить обещание.

1 Ответ

1 голос
/ 08 июня 2019

Я попытаюсь ответить на этот вопрос, не зная, что должна делать ваша функция или как она должна работать (потому что вы нам не сказали), так что терпите меня.

ОдинЭмпирическое правило с обещаниями заключается в том, что 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");
         });
}

Я считаю, что это должно правильно разрешить обещание, когда условиевыполнено, но у меня нет возможности проверить это, поэтому дайте мне знать, если у вас все еще есть проблемы с этим.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...