學習promise的過程中遇到一個關于隊列的問題,在開發(fā)中遇到一個問題,需要循環(huán)請求上傳的接口,但是下面的的方法好像沒有做到隊列,跪求大神幫我改造
需求是執(zhí)行完一個再執(zhí)行一個,直到最后一個,串行,對列的概念也不是很懂
function queue(files) {
let promise = Promise.resolve();
files.forEach(file => {
promise = promise.then(() => {
return new Promise(resolve => {
doThing(file, () => {
//上傳操作,訪問接口
resolve();
});
});
});
});
return promise;
}
queue([file1, file2, file3]).then(data => {
console.log(data);
});
不知道,你是不是要達到 串行上傳還是并行上傳的目的 ?
// 下面是串行上傳的
function queue(arr, handle) {
let index = 0
let length = arr.length
return new Promise((resolve, reject) => {
!(function next() {
try {
handle(arr[index])
.then(function () {
++index < length
? next()
: resolve()
})
.catch(reject)
} catch (err) {
reject(err)
}
})()
})
}
function upload(file) {
return new Promise((resolve, reject) => {
// 上傳文件
setTimeout(function () {
console.log(`upload ${file}`)
resolve()
}, file * 1000 )
})
}
queue(['3', '2', '1'], upload).then(data => {
console.log('ok');
}).catch(err => {
console.log('error', err)
})
樓主我來對你的代碼做點注釋,你自己再看看問題出在哪里
// 定義一個隊列構造器
function queue(files) {
// 使用Promise.resolve(val)生成一個Promise實例promise
// promise的狀態(tài)已轉換為Resolved狀態(tài),
// 這時promise仍可通過then方法獲取到Resolved的結果val(這里的val為空,所以是undefined)
let promise = Promise.resolve();
// 遍歷一次傳入的數(shù)組
files.forEach(file => {
// promise對象添加then方法,并將then方法的返回值重新賦值給promise并傳入resolve回調,
// 因為只傳了一個函數(shù)(這個函數(shù)沒有參數(shù),所以沒法捕獲上一次操作完成返回的值,
// 事實上,樓主也沒有在每次完成返回值,因為resolve()中沒有給值。)參數(shù),
// 所以reject的回調為undefined
promise = promise.then(() => {
// then.resolve回調中返回了一個新的Promise實例,新的實例通過構造的方式生成,
// 構造傳入了"resolve"這樣一個名字的函數(shù)參數(shù),作為promise的resolve回調,沒有reject
return new Promise(resolve => {
// 新構造的Promise實例的resolve回調中執(zhí)行異步上傳方法
doThing(file, () => {
//上傳操作,訪問接口
// 上傳完成resolve這個promise,但是沒有給下一個操作傳入值,
// 所以最后調用的data為空
resolve();
});
});
});
});
// 返回了新的promise引用,事實上,這個promise引用就已經是個隊列了
return promise;
}
// 這一步調用之后,做了什么事情?從這里再看這個queue內部的執(zhí)行過程,
// 調用之后,第一個上傳文件的操作就會立即啟動,上傳完成之后就會繼續(xù)上傳下一個,
// 直到這數(shù)組中都傳完, 最后一個操作的resolve被下面這個then捕獲
queue([file1, file2, file3])
//獲取了最后一個promise實例成功后resolve的值
.then(data => {
// 打印resolve的值
console.log(data);
});
另外,我這里還有個學習promise做的筆記,你可以回顧下
我的Promise筆記
問題是,這不是隊列,而是foreach
執(zhí)行promise
,遞歸一下就好了。
function doThing(file) {
return new Promise((resolve) => {
setTimeout(() => {
console.log('doThing', file)
resolve('result:' + file)
}, 500)
})
}
function queue(files, data = []) {
return new Promise((resolve) => {
if (files.length > 0) {
let file = files.shift();
doThing(file).then((res) => {
data.push(res)
resolve(queue(files, data))
})
} else {
resolve(data)
}
})
}
queue(['file1', 'file2', 'file3']).then(data => {
console.log(data);
});
題主你隊列的做法沒問題,只是最后沒有返回 data 而已。如果你需要 data 的話,可以在 resolve()
里返回。
另外自薦一下我的講堂:Promise 的 N 種用法,里面除了詳細介紹了 Promise 的各種用法,還專門寫了兩種隊列的處理。
北大青鳥APTECH成立于1999年。依托北京大學優(yōu)質雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學院和江蘇省首批服務外包人才培訓基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團創(chuàng)建于1999年,經過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術與教育服務機構,發(fā)展為教育服務業(yè)的綜合性企業(yè)集團,成為集合面授教學培訓、網(wǎng)
達內教育集團成立于2002年,是一家由留學海歸創(chuàng)辦的高端職業(yè)教育培訓機構,是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔任項目經理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍懿科技有限責任公司從事總經理職務負責iOS教學及管理工作。
浪潮集團項目經理。精通Java與.NET 技術, 熟練的跨平臺面向對象開發(fā)經驗,技術功底深厚。 授課風格 授課風格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應用開發(fā)經驗。曾經歷任德國Software AG 技術顧問,美國Dachieve 系統(tǒng)架構師,美國AngelEngineers Inc. 系統(tǒng)架構師。