Объем решения Promise - PullRequest
       8

Объем решения Promise

0 голосов
/ 31 марта 2020

Я вызываю функцию сторонней библиотеки. Он возвращает результаты (из их API) и функцию обратного вызова, которую я могу вызвать для следующего набора результатов.

Для простых вещей я создал фиктивную функцию третьей стороны.

Мой вопрос почему resolve не разрешает обещание после 1-го раза. Я предполагаю, что это происходит, потому что resolve находится внутри внутренней функции сторонней библиотеки.

Как я могу это исправить? Есть ли лучший способ добиться этого?

// Third party function, I cannot control
function thirdParty(callback) {

  var number = 0;

  var inner = function() {
    setTimeout(function() {
      next = inner;
      number = number + 10;
      callback(number, next);
    }, 1000);
  };

  inner();
}

// Code I can control
var nextFunc = null;

// Calls third party api
function getNumber() {
  return new Promise(function(resolve, reject) {
    if (nextFunc) {
      nextFunc();
    } else {
      thirdParty(function(number, next) {
      	console.log(number);
        nextFunc = next;
        resolve(number);
      });
    }
  });
}

function onButtonClick() {
  getNumber().then(function(number) {
    document.getElementById('ele').innerHTML += number + '<br>';
  });
}
<p>
<button type="button" onClick="onButtonClick();">Get Numbers
</button>
</p>
<p id="ele"></p>

1 Ответ

2 голосов
/ 31 марта 2020

Не разрешается, потому что nextFunc() в конечном итоге вызывает обратный вызов, переданный thirdParty() внутри первого обещания, и снова вызывает resolve() для этого обещания, которое уже выполнено, поэтому ничего не делает. Между тем, вы никогда не вызываете resolve() для второго обещания, поэтому оно никогда не решается.

Вот лучший подход единственный подход, который я могу придумать, учитывая ограничения вашего стороннего API (с ужасным дизайном интерфейса, на мой взгляд):

// Third party function, I cannot control
function thirdParty(callback) {

  var number = 0;

  var inner = function() {
    setTimeout(function() {
      next = inner;
      number = number + 10;
      callback(number, next);
    }, 1000);
  };

  inner();
}

// Code I can control
const numbers = getNumbers();

// Calls third party api
async function* getNumbers() {
  let resolve, next;

  yield new Promise(_resolve => {
    resolve = _resolve;

    thirdParty((number, _next) => {
      console.log(number);
      resolve(number);
      next = _next;
    });
  });

  while (true) {
    yield new Promise(_resolve => {
      resolve = _resolve;
      next();
    });
  }
}

document.querySelector('button').addEventListener('click', () => {
  numbers.next().then(({ value }) => {
    document.getElementById('ele').innerHTML += value + '<br>';
  });
});
<p>
  <button type="button">Get Numbers</button>
</p>
<p id="ele"></p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...