我正在尝试将promises用于一个小型新项目。但是我在理解如何使用函数更好地组织代码方面遇到了一些问题。问题是,我希望我的函数处理事情,我希望我的主要代码处理其他事情。所以,让我们看看这段代码:
in my function something
使用此代码,控制台将记录in my main call undefined
和.then()
:https://jsfiddle.net/hkacvw2g/
所以我找到了两个解决方案来解决我的问题,但我不喜欢它们:
第一个是创建变量,对变量使用function doSomething (isGoingToResolve = true) {
let promise = new Promise((resolve, reject) => {
if (isGoingToResolve) {
resolve("something")
} else {
reject("something else")
}
})
promise.then(response => {
console.log("in my function",response)
}).catch(error => {
console.log("in my function",error)
})
return promise
}
,然后返回变量(https://jsfiddle.net/hkacvw2g/1/):
function doSomething (isGoingToResolve = true) {
return new Promise((resolve, reject) => {
if (isGoingToResolve) {
resolve("something")
} else {
reject("something else")
}
}).then(response => {
console.log("in my function",response)
return new Promise(resolve => {
resolve(response)
})
}).catch(error => {
console.log("in my function",error)
return new Promise((resolve,reject) => {
reject(error)
})
})
}
第二个解决方案(https://jsfiddle.net/hkacvw2g/2/):
{{1}}
我错过了解决问题的更好解决方案吗?
答案 0 :(得分:2)
你可以简单地返回值(或重新抛出错误),它将在promise链中解决:
function doSomething (isGoingToResolve = true) {
return new Promise((resolve, reject) => {
if (isGoingToResolve) {
resolve("something")
} else {
reject("something else")
}
}).then(response => {
console.log("in my function",response)
return response;
}).catch(error => {
console.log("in my function",error)
throw error;
})
}
您可能不希望throw error
,这取决于您希望如何处理拒绝。这样当你重新抛出错误时,你应该在调用doSomething()
方法时捕获它。
答案 1 :(得分:1)
你可以写一个tap
函数,进入一个promise链,并在传递结果时执行一些操作,以及一个并行的tapCatch
函数,以便在重新抛出它们时利用错误:
const tap = fn => value => { fn(value); return value; };
const tapCatch = fn => reason => { fn(reason); throw reason; };
现在您可以将代码编写为:
function doSomething(isGoingToResolve = true) {
(isGoingToResolve ?
Promise.resolve("something") :
Promise.reject("something else")
)
.then( tap (response => console.log("in my function", response)))
.catch(tapCatch(error => console.log("in my function", error)));
}
doSomething()
.then(response => console.log("in my main call", response));
然而,实际上你的第一个解决方案更好。它通过无意中忘记或不意识到你必须在then
条款中返回原始值,或者重新抛出catch
条款来减少破坏承诺链的风险,这些条款只是意味着用于记录或其他副作用。
您还可以使用Promise
(我们称之为tap
)来污染thenDo
原型,使其更易于使用:
Promise.prototype.thenDo = function(ifFulfilled, ifRejected) {
return this.then(
value => { ifFulfilled(value); return value; },
reason => { ifRejected(reason); throw reason; });
};
Promise.prototype.catchDo = function(ifRejected) {
return this.catch(reason => { ifRejected(reason); throw reason; });
};
现在你可以写
了function doSomething(isGoingToResolve = true) {
(isGoingToResolve ?
Promise.resolve("something") :
Promise.reject("something else")
)
.thenDo (response => console.log("in my function", response))
.catchDo(error => console.log("in my function", error));
}