q库的一些用法

970 阅读2分钟

1、在node中一些用法

node 的核心异步函数不会返回promise; 它们采用了callback 的方式。 使用Q可以很容易的让其返回promise

Q.denodeify、Q.nfbind

将异步方法封装成promise

  • 特点:封装后返回一个方法,调用此方法得到promise
  • PS:此方法要求异步方法遵循nodejs的回调标准,否则可能出现错乱
const readFile = Q.nfbind(fs.readFile, './examples/test.txt',);
readFile('utf-8').then((error, data)=>{
    if (error) {
        console.error(error)
    } else {
        console.log(data)
    }
}, (error) => {
    console.error(error)
})

Q.nfcall、Q.nfapply

将异步方法封装成promise

  • 特点:封闭时就得传递调用方法的参数,直接得到promise。nfcall以逗号分割为参数,nfapply以数组为参数
  • PS:此方法要求异步方法遵循nodejs的回调标准,否则可能出现错乱
Q.nfcall(fs.readFile, './examples/test.txt', 'utf-8').then((error, data)=>{
    if(error){
       console.error(error) 
    } else {
        console.log(data)
    }
}, (error)=> {
    console.error(error) 
});

Q.npost、Q.ninvoke

Q.npost(fs, 'readFile', ['./examples/test.txt', 'utf-8']).then((error, data) => {
    if (error) {
        console.error(error)
    } else {
        console.log(data)
    }
}, (error) => {
    console.error(error)
});

//Q.ninvoke(fs, 'readFile', './examples/test.txt', 'utf-8').then((error, data)=>{

promise.nodeify

function fsReadFile(filePath, encodeing, callback){
    let defer = Q.defer();
    fs.readFile(filePath, encodeing, function (error, data) {
        if(error){
            defer.reject(error);
        } else {
            defer.resolve(data);
        }
    });
    return defer.promise.nodeify(callback);
}
fsReadFile('./examples/test.txt', 'utf-8', function (error, data) {
    if (error) {
        console.error(error)
    } else {
        console.error(data)
    }
});

defer.makeNodeResolver

手动封装一个promise

  • 特点:和deferd原理差不多,只不过用了deferd自带的方法省掉了我们手动实现reject方法、resolve方法
  • PS:此方法要求异步方法遵循nodejs的回调标准,否则可能出现错乱
function fsReadFile(filePath, encodeing, callback) {
    let defer = Q.defer();
    fs.readFile(filePath, encodeing, defer.makeNodeResolver());
    return defer.promise;
}
fsReadFile('./examples/test.txt', 'utf-8').then((error, data)=> {
    if (error) {
        console.error(error)
    } else {
        console.error(data)
    }
});

2、Promise 函数方法

Q.fcall

function mytest(a, b) {
    console.log('In mytest');
    return 'aaa'
}

Q.nfcall(mytest, 1, 2).then(function (value) {
    console.log('value', value);
});

而在Q.nfcall中,Q期望mytest调用通过回调传递(错误,值),Q然后用值调用下一个回调

function mytest(a, b, cb) {
    console.log('In mytest');
    cb(null, 'aaa');  //区别多了个cb
}

Q.nfcall(mytest, 1, 2).then(function (value) {
    console.log('value', value);
});

Q.fapply、Q.fbind

类似Q.fcall方法

3、Promise 对象方法

promise.get(propertyName)

Q([{ foo: "bar" }, { foo: "baz" }]).get(0).get("foo").then((value)=>{
    console.log('value', value);
})

promise.keys()

Q({ foo: "foo" , bar: "bar" }).keys().then((value)=>{
    console.log('value', value); //['foo', 'bar']
})

promise.invoke(methodName, ...args)

function foo(a, b , c){
    return [a, b, c]
}
function bar(a, b, c) {
    return [a, b]
}
Q({foo, bar}).invoke('foo', 1, 2, 3).then((value)=>{
    console.log('value', value); //[1, 2, 3]
})

promise.post(methodName, args)

同上promise.invoke,参数换成数组[1,2,3]

Promise 数组方法

promise.all

promise.allSettle

 Q.allSettled([Q('resolve'), Q.reject('resolve2')])
.spread((a, b)=>{
    console.log(a, b);
}).catch((error)=>{
    console.log(error);
})

promise.spread

取代then,将结果展开

Q.all([Q('resolve'), Q('resolve2')])
.spread((a, b)=>{
    console.log(a, b);
}).catch((error)=>{
    console.log(error);
})

参考链接

git API文档

文档链接