我试图以递归方式调用promise函数。
以下调用service.getSentenceFragment()从一个句子返回最多5个字母,即来自'helloworld'的'hello'。提供nextToken值作为调用的参数将返回序列中的后5个字母。即'世界'。以下代码返回'hellohelloworldworld'并且不会登录到控制台。
to
答案 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);
}
});
});
}