In my former post I was able to solve my Promise problem by looking at some examples provided by this community. I hope this one will be easy to solve too, although I just can't get my head around it. For the first time in my life, I experience being fluent in PHP language is a burden.
My code looks like this:
let getProducts = function(){
countProducts
.then(function(number){
var name = '';
let list = [];
getProductNames(name)
.then(function(names){
names.forEach(function(el){
list.push(el);
});
name = list.pop();
getProductNames(name)
.then(function(names){
names.forEach(function(el){
list.push(el);
});
... and some more code to put the names in a table
the getProductNames function looks like this:
var getProductNames =
function(name) {
return new Promise(
function(resolve, reject){
xyz.api.checkProducts(name, 1000, function(err, names){
if (err){
reject(err);
} else {
resolve(names);
}
});
}
);
}
This works because I know I have less than 2000 products, each check returns 1000 products, so I have to run the getProductNames function twice.
What I am looking for is a way to make this into a loop so it automatically runs the needed number of runs.
The problem with the api call is that it needs a productname to start with. The first run is without a name, this returns the first 1000. For the second run I need the last found productname of run 1, for run 3 I need the last found productname of 2, and so on.
There are different ways to determine whether another run is needed:
I just don't know how to loop and where. I assume the solution is found by adding a helper function, but when I try that I get caught in values not being available and so on.
You don't have to solve my problem, but I would be very grateful if some one could supply an example of the needed structure or some internet source that describe this structure. The examples I found don't use values from the former runs.
答案 0 :(得分:1)
BUILDARGS did not return a HASH reference
答案 1 :(得分:1)
为了更好地理解代码,我在需要的地方添加了注释。随便问什么。
注意:此代码未经测试,可能无法按原样工作。这只是向您展示如何实际操作。
note1:您可能还想看看async-await
,它们与promise一样,但是在语法上更加可读和清晰
let getProducts = function() {
// return your promise, you may want to getProducts.then()
return countProducts()
.then(function(number) {
return getProductNames(number);
})
.catch(function(err) { // always put a catch
console.log('there was an error', err)
})
}
// make your getProductsName take in number value
// the name it takes is empty by default, we will provide name when we recursively call it
let getProductNames = function(number, name = ''){
// check if your number is less than -1000 here , why ? keep reading the code
if (number < -1000) return [];
const nameCount = 1000;
let names = []
return callAPI({name, nameCount})
.then(function(namesFromCallAPI) {
names = names.concat(namesFromCallAPI); // you can concat two arrays at once
// I do not know why you are poping the names, since it will mutate the array
// use any one as per requirement
let newName = names.pop();
// OR let newName = names[names.length-1]; which will not mutate the array
// recursively call the function by decreasing it by your nameCount
// when your number is 500, it can still call but the result will be -500, which will run
// in the next iteration -500-1000 will be -1500 which is < -1000 (explanation of base condition)
return getProductNames(number - nameCount, newName)
})
.then(function(res) {
// the result from getProductNames is again concatinated to our names and returned
return names.concat(res);
})
.catch(function(err) {
// always put a catch in your chain
console.log('There was an error in our recursive function', err);
})
}
// make a separate function that would api call
// put any parameters that you may need to make customizable here
let callAPI = function(params) {
return new Promise(function(resolve,reject) {
xyz.api.checkProducts(params.name, params.nameCount, function(err, names){
if (err){
reject(err);
} else {
resolve(names);
}
});
})
}