正在阅读 cmets 并想澄清一下:
你应该怎么写下面这个简单的函数 test() { return new Promise((resolve,reject) => { setTimeout(() => { resolve(42); }); }); }
这看起来像是一个立即解析为 42 的承诺,因此您可以:
const test = _=>Promise.resole(42);
如果您想要一个在特定时间解析并多次使用它的承诺,您可以编写以下内容:
const later = time => value =>
new Promise(
(resolve,reject)=>
_=>resolve(value),
time
);
const afterOneSecond = later(1000);
afterOneSecond("resolves after one second");
如果您想稍后拒绝:
later(1000)(Promise.reject("rejects after one second"));
如果您使用真正的 Promise 而不是模拟的 Promise 进行测试,并且需要在没有控制台警告您的情况下传递被拒绝的 Promise 并遇到“未捕获”断点,您可以这样做:
const p = Promise.reject("rejects after one second");
p.catch(ignore=>ignore);//catch it
later(1000)(p);//pass promise without catch to later
如果你有一个函数可以返回一个承诺并处理你可以做的值。
myFunction()
.then(
something=>something.data
)
.then(
data=>...
)
如果你想检查 something.data 是否不为空,如果你想拒绝,你可以这样做:
myFunction()
.then(
something=>
(something&&something.data.length!==0)
? something.data
: Promise.reject("Data cannot be empty")
)
.then(
data=>...
)
.catch(
e=>
(e==="Data cannot be empty")
? "do something special"
: Promse.reject(e)//keep rejecting, other error
);
如果您有一个可以抛出的同步函数,它是您的 Promise 链中的第一个函数,并且您希望它抛出的内容最终成为被拒绝的 Promise,您可以执行以下操作:
const syncFunctionThatThrows = arg => {
if(arg===1){
throw "arg cannot be 1";
}
return arg;
};
//starting promise chain with synchronous function that can throw
// if it throws the error is absorbed by the chain and produces
// a rejected promise
Promise.resolve(1)//going to pass 1 to syncFunctionThatThrows
.then(syncFunctionThatThrows);
要使用回调 API 作为 Promise,您可以这样做:
const asPromise = object => fn => args =>
new Promise(
(resolve,reject)=>
fn.apply(
object,
args.concat([
(...result)=>
(result[0])//first argument of callback is error
? reject(result[0])//reject with error
: resolve(result.slice(1,result.length))//resolve with result(s)
])
)
);
const callbackApiObjectAsPromise = asPromis(callbackApi);
callbackApiObjectAsPromise(callbackApi.someMethod)(["arg1","arg2"])
.then(
result=>...
)
//example of mysqljs
const connectionAsPromise = asPromise(connection);
connectionAsPromise(connection.query)([
'SELECT * FROM `books` WHERE `author` = ?',
['David']
]).then(
([results, fields])=>...
);
如果您不喜欢DIY,可以按照Pointy 的建议使用promisifyAll 或promisify。