递归调用promise函数

时间:2018-03-20 14:48:15

标签: javascript recursion promise

我试图以递归方式调用promise函数。

以下调用service.getSentenceFragment()从一个句子返回最多5个字母,即来自'helloworld'的'hello'。提供nextToken值作为调用的参数将返回序列中的后5个字母。即'世界'。以下代码返回'hellohelloworldworld'并且不会登录到控制台。

to

2 个答案:

答案 0 :(得分:2)

执行此操作时的原因:

getSentence(data.NextToken);

新的Promise链启动,当前链永远保持待定状态。可能会这样做:

getSentence(data.NextToken).then(resolve, reject)

...但实际上你可以将整个事情美化为:

async function getSentence(){
  let sentence = "", token;

  do {
   const partial = await getSentenceFragment(token);
   sentence += partial.fragment;
   token = partial.NextToken;
  } while(token)

  return sentence;
}

请注意getSentenceFragment中的此陷阱 - 如果data是真实但data.length为0,则您的代码达到死胡同并且承诺将超时

// from your original getSentenceFragment...
if (data) {
  if (data.length !== 0) {
    resolve(data);
  }
  /* implicit else: dead end */
  // else { return undefined }
} else {
  reject(error);
}

相反,使用if合并两个&&语句,现在我们的承诺将始终解析或拒绝

// all fixed!
if (data && data.length > 0)
  resolve(data);
else
  reject(error);

答案 1 :(得分:1)

您可以递归调用这样的承诺:

getSentence("what is your first token?")
.then(function (data) {
  console.log(data);
});

function getSentence(nextToken) {
  const recur = (nextToken,total) => //no return because there is no {} block so auto returns
    getSentenceFragment(nextToken)
    .then(
      data => {
        if (data.nextToken != null && data.nextToken != 'undefined') {
          return recur(data.NextToken,total + data.fragment);
        } else {
          return total + data.fragment;
        }
    });//no catch, just let it go to the caller
  return recur(nextToken,"");
}

function getSentenceFragment(nextToken) {
  return new Promise((resolve, reject) => {
    service.getSentenceFragment({ NextToken: nextToken }, function (error, data) {
      if (data) {
        if (data.length !== 0) {
          resolve(data);
        }
      } else {
        reject(error);
      }
    });
  });
}