Javascript 如何使函数既可以使用wait,又可以使用callback?

Javascript 如何使函数既可以使用wait,又可以使用callback?,javascript,ecmascript-6,Javascript,Ecmascript 6,我想创建一个可以同时使用异步/等待和普通回调模式的函数。因此,类似于以下内容的方法将起作用: function myFunc(cb) { setTimeout(function(){ //something async console.log('hello'); cb(); }); } myFunc(function(){ console.log('world'); }); 但下面的方法行不通 function myFunc(cb = fun

我想创建一个可以同时使用异步/等待和普通回调模式的函数。因此,类似于以下内容的方法将起作用:

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');
})();

我知道等待工作需要返回承诺,尽管我对如何接受回调和返回承诺没有什么想法,但我希望看到一些正确的方法来做到这一点。

您可以这样使用这两种方法

function myFunc (giveback, callback) {
    return new Promise((resolve, reject) => {
        setTimeout(function() {
           resolve(giveback);
           if (typeof callback === 'function') callback(null, giveback);
        }, 1000)
    }
}

你可以这样使用两者

function myFunc (giveback, callback) {
    return new Promise((resolve, reject) => {
        setTimeout(function() {
           resolve(giveback);
           if (typeof callback === 'function') callback(null, giveback);
        }, 1000)
    }
}

通常,实现这一点的方法是检查显式传递的参数数量,并相应地采取行动

如果希望
myFunc()
同时实现这两种样式,下面是一个可能的实现:

函数myFunc(cb){
//一些异步逻辑
const p=新承诺((解决、拒绝)=>{
设置超时(()=>{
//在这里传递一些值
解决(‘成功’)
}, 1000)
设置超时(()=>{
//在这里传递一些错误
拒绝(新错误(‘有东西坏了’))
},Math.random()*2000)//50%的失败概率
})
if(arguments.length<1){
//援用承诺风格
返回p
}else if(cb的类型==‘函数’){
//使用有效函数调用回调样式
p、 然后(result=>{cb(null,result)},error=>{cb(error)})
}否则{
//使用非函数以回调方式调用
//应产生致命错误
抛出新类型错误('cb不是函数')
}
}
//用法
试一试{
//没有函数参数的调用无效
myFunc('字符串不实现[[Call]]')
}捕获(错误){
console.log(错误消息)
}
//回调样式
myFunc((错误,值)=>{
if(error)返回console.log(`callbackwitherror:${error.message}`)
log(`callback with value:${value}`)
})
//承诺式
myFunc()。然后(值=>{
log(`promise with value:${value}`)
},错误=>{
log(`promise with error:${error.message}`)

})
通常,实现这一点的方法是检查显式传递的参数数量,并相应地采取行动

如果希望
myFunc()
同时实现这两种样式,下面是一个可能的实现:

函数myFunc(cb){
//一些异步逻辑
const p=新承诺((解决、拒绝)=>{
设置超时(()=>{
//在这里传递一些值
解决(‘成功’)
}, 1000)
设置超时(()=>{
//在这里传递一些错误
拒绝(新错误(‘有东西坏了’))
},Math.random()*2000)//50%的失败概率
})
if(arguments.length<1){
//援用承诺风格
返回p
}else if(cb的类型==‘函数’){
//使用有效函数调用回调样式
p、 然后(result=>{cb(null,result)},error=>{cb(error)})
}否则{
//使用非函数以回调方式调用
//应产生致命错误
抛出新类型错误('cb不是函数')
}
}
//用法
试一试{
//没有函数参数的调用无效
myFunc('字符串不实现[[Call]]')
}捕获(错误){
console.log(错误消息)
}
//回调样式
myFunc((错误,值)=>{
if(error)返回console.log(`callbackwitherror:${error.message}`)
log(`callback with value:${value}`)
})
//承诺式
myFunc()。然后(值=>{
log(`promise with value:${value}`)
},错误=>{
log(`promise with error:${error.message}`)

})
以下是我前面描述的功能示例:

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)
})

下面是我前面描述的功能示例:

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)
})

通常,当我在库中看到这一点时,函数接受2个参数,第二个参数是回调,如果省略该参数,它将返回一个承诺。通常当我在库中看到这一点时,函数接受2个参数,第二个参数是回调,如果省略该参数,它将返回一个承诺。这将导致运行时错误,因为
回调可能无法传递。即
uncaughttypeerror:undefined不是一个函数
。这将导致运行时错误,因为可能无法传递
回调
。即
未捕获类型错误:未定义不是函数