gpt4 book ai didi

javascript - 如果未传递可选回调,如何使函数返回 promise ?

转载 作者:行者123 更新时间:2023-12-01 01:49:30 25 4
gpt4 key购买 nike

我可以想出

 function squareAsync(val, callback) {
if (callback) {
setTimeout(() => {
if (Math.random() < 0.5) {
callback(undefined, val * val);
}
else {
callback(new Error('Failed!'));
}
}, 2000);
}
else {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve(val * val);
}
else {
reject(new Error('Failed!'));
}
}, 2000);
});
}
}

我找到了另一种方法

 function squareAsync1(val, callback) {
let p = new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
resolve(val * val);
}
else {
reject(new Error('Failed!'));
}
}, 2000);
});
if (callback) {
p.then(d => {
callback(undefined, d);
}, e => {
callback(e);
});
}
return p;
}

其中哪一个更好或者有更标准和优雅的方法来做到这一点?我们可以使用async/await来做到这一点吗?

最佳答案

你可以这样做:

function squareAsync(val, callback) {
const timeout = function(res, rej){
setTimeout(function(){
if (Math.random() < 0.5)
res(val*val);
else
rej(new Error('Failed!'));
}, 2000);
}

return typeof callback === 'function'
? timeout(callback.bind(null, undefined), callback)
: new Promise(timeout);
}

// CALLBACK EXAMPLE
squareAsync(5, (err, val) => {
if (err)
console.log(`Callback: ${err}`);
else
console.log(`Callback: ${val}`);
})

// PROMISE EXAMPLE
squareAsync(5)
.then(val => console.log(`Promise: ${val}`))
.catch(err => console.log(`Promise: ${err}`))

说明

  1. 将您的 setTimeout 调用包装到一个包装函数 timeout 中,这样您就不必重复几乎相同的代码。
  2. timeout函数接受两个参数:resrej(解决和拒绝)
  3. 如果通过函数传递回调,则返回 timeout,否则返回 new Promise(timeout)

现在发生了什么:

return typeof callback === 'function'
? timeout(callback.bind(null, undefined), callback)
: new Promise(timeout);

翻译过来就是:

if (typeof callback === 'function'){
// Bind `null` as `this` value to `callback
// and `undefined` as its first argument (because no error).
// Need to to this because in `timeout` function,
// we call `res` with only 1 argument (computed value) if success.
const resolve = callback.bind(null, undefined);

// Don't need to bind anything
// because the first argument should be error.
const reject = callback;

// Call the function as if we are in a Promise
return timeout(resolve, reject);
}

// Use `timeout` function as normal promise callback.
return new Promise(timeout);

希望你能理解。如果有困惑,请随时发表评论。

More about bind.

关于javascript - 如果未传递可选回调,如何使函数返回 promise ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51665277/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com