我已经读过你应该在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
(标有//******
的行)的值来解析的承诺,以便我可以在其他地方执行以下操作:< / p>
myFooInstance.changeName('/path', 'New Name').then(page=> {
// Do something with the returned saved page
});
答案 0 :(得分:6)
如何让changeName返回一个将使用this.savePage
的值解析的promise
从savePage
处理程序返回promise then
返回值。由then
创建的承诺将自己从属于该承诺。
.then(page=> {
page.name = newName;
return this.savePage(path, page);
})
另外,你已经说过你希望调用者能够在changePage
的返回值上使用promise,但是你没有从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);
});
}
}
答案 1 :(得分:0)
您只需返回承诺,然后从任何嵌套承诺返回:
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
})
}
}