Итак, я собираюсь сделать некоторые предположения здесь, так что поправьте меня, если я ошибаюсь, и я исправлю их. Надеюсь, что в этом я помогу прояснить ваше понимание.
Простой способ думать о async/await
заменяет необходимость в .then(callback)
. Я предпочитаю использовать await
, если в async function
.
const getFiles = async function(token, reponame) {
try {
var gh = new GitHub({
token: token
});
reponame = reponame.split("/");
// edit: I removed await from the line below as your original code
// did not treat it as a promise
const repo = gh.getRepo(reponame[0], reponame[1]);
// unused code from your post
let head = new Headers();
head.append("Authorization: ", "token " + token);
// the await below assumes that repo.getContents
// will return a promise if a callback is not provided
const files = await repo.getContents(null, "content", true);
// updating the code below so that the file requests run in parallel.
// this means that all requests are going to fire off basically at once
// as each fetch is called
const fileRequests = files.map(file => fetch(file.downloadURL))
// you wont know which failed with the below.
const results = (await Promise.all(fileRequests)).map(res => res.text)
return results
} catch (err) {
// handle error or..
throw err;
}
};
Этот код не проверен. Я не использовал API GitHub, поэтому я думаю, что делает каждый звонок. Если gh.getRepo
или repo.getContents
не возвращают обещания, потребуется некоторая корректировка.
В случае, если используемая вами библиотека github не вернет обещание, если обратный вызов не предоставлен:
const getFiles = async function(token, reponame) {
try {
var gh = new GitHub({
token: token
});
reponame = reponame.split("/");
const repo = await gh.getRepo(reponame[0], reponame[1]);
let head = new Headers();
head.append("Authorization: ", "token " + token);
const getContents = new Promise((res, rej) => {
repo.getContents(null, "content", true, (err, files) => {
if (err) {
return rej(err);
}
res(files)
})
})
const fileRequests = (await getContents).map(file => fetch(file.downloadURL))
return (await Promise.all(fileRequests)).map(res => res.text)
} catch (err) {
// handle error or..
throw err;
}
};
вот пример использования async / await, который использует новое обещание для обещания обратного вызова:
const content = document.getElementById("content")
const result = document.getElementById("result")
async function example(){
content.innerHTML = 'before promise';
const getContents = new Promise((res, rej) => {
setTimeout(()=> {
res('done')
}, 1000)
})
const res = await getContents
content.innerHTML = res
return res
}
example().then((res)=> {
result.innerHTML = `I finished with <em>${res}</em> as a result`
})
<div id="content"></div>
<div id="result"></div>
Вот почему я изначально написал ответ с for ... of l oop, который ожидал каждого запроса. Все обещания выполняются в основном сразу:
const content = document.getElementById("content")
const result = document.getElementById("result")
async function example() {
const promises = []
content.innerHTML = 'before for loop. each promise updates the content as it finishes.'
for(let i = 0; i < 20; i++){
const promise = new Promise((resolve, reject) => {
setTimeout(()=> {
content.innerHTML = `current value of i: ${i}`
resolve(i)
}, 1000)
})
promises.push(promise)
}
const results = await Promise.all(promises)
return results
}
example().then(res => result.innerHTML= res.join(', '))
content:
<div id="content"></div>
result:
<div id="result"></div>