我想在do while循环中调用异步函数,只有在函数没有返回值时才退出。 有没有办法管理这个,而不必在回调之外实际等待?
这里的代码显然总是在第一个循环中退出,因为在评估while()时函数还没有被回调:
var i = 0;
do {
var foundListing;
if (i) {
listing.slug = listing.slug + '-' + (i + 1);
}
listingService.getListingBySlug(listing, function(error, pFoundListing) {
if (error) {
return callback(util.errorParser(error));
} else if (Object.keys(pFoundListing).length) {
foundListing = pFoundListing;
i++;
}
});
//Do I have to wait here???
} while (foundListing && Object.keys(foundListing).length);

澄清: 这里的要点是生成一个独特的slug。如果slug已经存在,我会附加一个数字并再次检查它是否存在。当我找到尚未存在的号码时,我已经完成了。
更新 我发现了一种使用递归的方法。我将工作代码段发布为answer。
答案 0 :(得分:1)
我没有测试它的可能性,但也许递归函数应该这样做:
const listingService = {
getListingBySlug(listing, callback) {
setTimeout(() => {
if (listing.slug === 'listing-5') {
callback(
false,
{
name: 'Listing 1',
slug: 'listing-1',
}
);
}
else {
callback(false, {});
}
}, 1000);
},
};
function checkListingExists(slug) {
return new Promise((resolve, reject) => {
const listing = { slug };
listingService.getListingBySlug(listing, (error, pFoundListing) => {
if (error) {
reject(error);
} else if (Object.keys(pFoundListing).length) {
resolve(pFoundListing);
} else {
resolve(false);
}
});
});
}
function nextListing(prefix, index) {
checkListingExists(prefix + '-' + index)
.then((listing) => {
if (listing === false) {
nextListing(prefix, index + 1);
} else {
console.log(listing);
}
})
.catch(() => {
// deal with error response
});
}
nextListing('listing', 0);

答案 1 :(得分:0)
在这种情况下你应该使用诺言。你可以这样做。
var DEFERRED = require('deferred');
var deferred = new DEFERRED();
var i =0;
while(1) {
listingService.getListingBySlug(listing, function(error, pFoundListing) {
if (error) {
return callback(util.errorParser(error));
deferred.reject();
break;
} else if (Object.keys(pFoundListing).length) {
i++;
listing.slug = listing.slug + '-' + (i + 1);
if(pFoundListing) {deferred.resolve()}
break;
}
});
deferred.promise.then(function() {
// You will have the listing.slug value here.
});
顺便说一句,你不应该使用Object.keys()来确定对象是否为空。只需在utils文件中的某处创建自己的isEmpty方法并检查属性。如果您的pFoundListing非常大,则会出现严重的性能问题。对于小对象(数组),您不会注意到差异。
答案 2 :(得分:0)
我按照Giacomo Cosimato的建议使用递归工作。
以下是有效的摘录:
listingController.js
saveListing: function(listing, callback) {
listingService.findOpenSlug(listing, listing.slug, 1, function(error, listing) {
if (error) {
return callback(util.errorParser(error));
} else {
listingService.saveListing(listing, function(error, savedListing) {
//do some work
});
}
});
}

listingService.js
var classMethods = {
findOpenSlug: function(listing, baseSlug, i, callback) {
listingRepository.getListingBySlug(listing.slug, function(error, foundListing) {
if (error) {
return callback(error);
} else if (Object.keys(foundListing).length) {
listing.slug = baseSlug + '-' + (i + 1)
i++;
classMethods.findOpenSlug(listing, baseSlug, i, callback);
} else {
callback(null, listing);
}
});
},
[...]
}