[英]How can I eliminate these nested Promises?
我讀過你應該避免JavaScript 中的嵌套承諾,因為它們往往是一種反模式,但我無法弄清楚如何在我的特定用例中避免它們。 希望比我更有經驗的人能看出我哪里出錯了? 任何建議將不勝感激!
本質上,我正在異步檢索一些數據,處理它並捕獲可能的錯誤,然后異步保存一些數據。 這是一個非常簡單的例子:
class Foo {
changeName(path, newName) {
this.getPage(path) // AJAX call, returns a promise with type Page,
// may throw an Error if the page does not exist.
.then(page=> {
// Some modifications are made to page, omitted here
return page
})
.catch(e=>{
if(e instanceof PageDoesNotExistError) {
return new Page();
}
})
.then(page=> {
page.name = newName;
this.savePage(path, page); // ******
// I want my outer changeName method to return this ^ promise,
// or at least a promise that will resolve when this promise
// resolves, with the same value.
})
}
}
我怎樣才能讓changeName
返回一個將使用this.savePage
的值(標有//******
的行)解析的承諾,以便我可以在其他地方做這樣的事情:
myFooInstance.changeName('/path', 'New Name').then(page=> {
// Do something with the returned saved page
});
我怎樣才能讓 changeName 返回一個可以用 this.savePage 的值解析的承諾
返回來自then
處理程序的承諾savePage
返回。 這會將then
創建的 promise 解析為來自savePage
,這意味着then
創建的 promise 將根據savePage
執行或拒絕執行。 (如果您有興趣,可以在我的博客文章中詳細了解該術語。)
.then(page=> {
page.name = newName;
return this.savePage(path, page);
})
另外,您已經說過您希望調用者能夠對changePage
的返回值使用承諾,但您沒有從changePage
返回任何內容。 您需要在整個結構前添加return
,以便返回最終的承諾。
changeName(path, newName) {
return this.getPage(path) // AJAX call, returns a promise with type Page,
// ...
(有關完整版本,請參見下文。)
旁注:您在此處等待發生錯誤:
.catch(e=>{
if(e instanceof PageDoesNotExistError) {
return new Page();
}
})
如果e
不是PageDoesNotExistError
的實例,則您將拒絕轉換為值為undefined
,因為在這種情況下您的catch
處理程序不會返回顯式值。 如果你想傳播錯誤,你需要用throw e
或return Promise.reject(e)
來做到這一點:
.catch(e=>{
if(e instanceof PageDoesNotExistError) {
return new Page();
}
return Promise.reject(e);
})
把這三樣東西放在一起:
class Foo {
changeName(path, newName) {
return this.getPage(path)
.then(page=> {
// Some modifications are made to page, omitted here
return page;
})
.catch(e=>{
if(e instanceof PageDoesNotExistError) {
return new Page();
}
return Promise.reject(e);
})
.then(page=> {
page.name = newName;
return this.savePage(path, page);
});
}
}
您只需返回承諾,然后從任何嵌套的承諾中返回:
class Foo {
changeName(path, newName) {
return this.getPage(path)
.catch(e => {
if(e instanceof PageDoesNotExistError) {
return new Page();
}
})
.then(page=> {
page.name = newName;
return this.savePage(path, page); // assuming that this is a promise
})
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.