我想创建一个可以同时使用async / await和通常的回调模式的函数。所以像下面这样的东西会起作用:
get_dict
但是下面的内容不会起作用
function myFunc(cb) {
setTimeout(function(){ //something async
console.log('hello');
cb();
});
}
myFunc(function(){
console.log('world');
});
我理解function myFunc(cb = function(){}) {
setTimeout(function(){ //something async
console.log('hello');
cb();
}, 1000);
}
(async ()=> {
await myFunc();
console.log('world');
})();
工作await
需要返回一个承诺,尽管我对如何采取回调和回报承诺的想法很少,但我还是喜欢看到一些正确的方法来做到这一点。
答案 0 :(得分:3)
你可以像这样使用
function myFunc (giveback, callback) {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve(giveback);
if (typeof callback === 'function') callback(null, giveback);
}, 1000)
}
}
答案 1 :(得分:2)
通常,实现此目的的方法是检查显式传递的参数数量,并采取相应的行动。
如果您希望myFunc()
同时实现这两种风格,可以采用以下方式实现:
function myFunc(cb) {
// some async logic
const p = new Promise((resolve, reject) => {
setTimeout(() => {
// pass some value here
resolve('success')
}, 1000)
setTimeout(() => {
// pass some error here
reject(new Error('something broke'))
}, Math.random() * 2000) // 50% chance of failure
})
if (arguments.length < 1) {
// invoked promise-style
return p
} else if (typeof cb === 'function') {
// invoked callback-style with valid function
p.then(result => { cb(null, result) }, error => { cb(error) })
} else {
// invoking in callback-style with a non-function
// should produce a fatal error
throw new TypeError('cb is not a function')
}
}
// usage
try {
// invalid invocation without function parameter
myFunc('strings do not implement [[Call]]')
} catch (error) {
console.log(error.message)
}
// callback-style
myFunc((error, value) => {
if (error) return console.log(`callback with error: ${error.message}`)
console.log(`callback with value: ${value}`)
})
// promise-style
myFunc().then(value => {
console.log(`promise with value: ${value}`)
}, error => {
console.log(`promise with error: ${error.message}`)
})
上述实现在使用回调调用时故意不返回promise。如果你想它这样做,那么我推荐这种方法,因为它更灵活一点(即如果你想传递一个回调并仍然把它视为当时的能力):
function myFunc(cb = () => {}) {
if (arguments.length > 0 && typeof cb !== 'function') {
// invoking in callback-style with a non-function
// should produce a fatal error
throw new TypeError('cb is not a function')
}
// some async logic
return new Promise((resolve, reject) => {
setTimeout(() => {
// pass some value here
resolve('success')
}, 1000)
setTimeout(() => {
// pass some error here
reject(new Error('something broke'))
}, Math.random() * 2000) // 50% chance of failure
}).then(result => {
cb(null, result)
// propagate result
return result
}, error => {
cb(error)
// propagate error
throw error
})
}
// usage
try {
// invalid invocation without function parameter
myFunc('strings do not implement [[Call]]')
} catch (error) {
console.log(error.message)
}
// callback-style
myFunc((error, value) => {
if (error) return console.log(`callback with error: ${error.message}`)
console.log(`callback with value: ${value}`)
})
// promise-style
myFunc().then(value => {
console.log(`promise with value: ${value}`)
}, error => {
console.log(`promise with error: ${error.message}`)
})
// using both styles
myFunc((error, value) => {
if (error) return console.log(`mixed callback with error: ${error.message}`)
console.log(`mixed callback with value: ${value}`)
}).then(value => {
console.log(`mixed promise with value: ${value}`)
}, error => {
console.log(`mixed promise with error: ${error.message}`)
})
答案 2 :(得分:1)
以下是我之前描述的功能示例:
const myFunc = (obj, callback) => {
if (!callback) {
const performWork = async () => obj
return new Promise(async (resolve, reject) => {
const value = await performWork()
resolve(value)
})
}
const cb = obj
callback(cb)
}
const test = { test: 1337 }
// Promise version
myFunc(test)
.then((res) => console.log('Promise version', res))
// Callback version
myFunc(test, (res) => {
console.log('Callback version', res)
})