Я хочу создать одно Promise, которое внутренне вызывает последовательность асинхронных методов в последовательности и возвращает результаты этих методов, конкатенированные в упорядоченном массиве, как только последний метод вернется.
Я пытался это сделать:
const getArray = function (thisArray) {
return new Promise ( function (resolve, reject) {
if (thisArray.length < 3) {
setTimeout(function() {
console.log('adding element');
thisArray.push(thisArray.length);
getArray(thisArray);
}, 1000);
} else {
console.log(thisArray);
console.log('resolving');
resolve(thisArray);
}
});
}
getArray([]).then(function(data) {
console.log('thened');
console.log(data);
})
но он никогда не называет then()
. Как я могу это сделать?
Вы не за горами, вы просто должны быть уверены в том, что будете называть resolve
для каждого new Promise
. Если вы все еще строите массив, вы передаете полученное обещание из вашего рекурсивного вызова getArray
; в противном случае вы передаете массив:
const getArray = function(thisArray) {
return new Promise((resolve, reject) => {
if (thisArray.length >= 3) {
// All done
resolve(thisArray);
} else {
// Do something async...
setTimeout(() => {
// ...add the result
console.log('adding element');
thisArray.push(thisArray.length);
// ...and recurse
resolve(getArray(thisArray));
}, 1000);
}
});
}
getArray([]).then(data => {
console.log('done');
console.log(data);
});
Это немного чище, если вы getArray
функцию, выполняющую работу async от getArray
, и убедитесь, что функция, выполняющая работу async, возвращает обещание. Для наших целей мы можем просто обернуть setTimeout
в обертке Promise:
const setTimeoutP = (cb, delay) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(cb());
}, delay);
});
};
затем:
const getArray = thisArray => {
if (thisArray.length >= 3) {
return Promise.resolve(thisArray);
}
return setTimeoutP(() => {
console.log("adding element");
thisArray.push(thisArray.length);
});
};
Живая копия:
const setTimeoutP = (cb, delay) => {
return new Promise(resolve => {
setTimeout(() => {
resolve(cb());
}, delay);
});
};
const getArray = thisArray => {
if (thisArray.length >= 3) {
return Promise.resolve(thisArray);
}
return setTimeoutP(() => {
console.log("adding element");
thisArray.push(thisArray.length);
return getArray(thisArray);
}, 1000);
};
getArray([]).then(data => {
console.log('done');
console.log(data);
});