使用这两种方法来宣传Socket.IO的server.close有什么区别?

时间:2017-08-19 13:59:59

标签: javascript asynchronous ecmascript-6 async-await

我试图找到一些方法来编写我的一般promisify函数来使用async并等待socket.io
这是我的代码第一个未能完成而第二个成功没有问题。

这两者有什么区别?为什么第一个会失败?

function promisify (func) {
    return new Promise((resolve, reject) => func(() => {
        resolve()    
        console.log('closeServer')
    }))}
async function timer1 () {
    await Promise.resolve(promisify(server.close))
}



function closeServer () {
    return new Promise((resolve, reject) => server.close(() => {
        resolve()
        console.log('closeServer')
    }))}
async function timer2 () {
    await Promise.resolve(closeServer())
}

让我告诉你们这些日志,
第二个

> nodemon src/index.js --exec babel-node --presets es2015

[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `babel-node src/index.js --presets es2015`
Server listening at port 3000
^C(node:28061) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): TypeError: Cannot read property '_handle' of undefined
(node:28061) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

第二个

> nodemon src/index.js --exec babel-node --presets es2015

[nodemon] 1.11.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `babel-node src/index.js --presets es2015`
Server listening at port 3000
^CcloseServer

1 个答案:

答案 0 :(得分:0)

你的第一个立即调用该函数,当它被回调时,用undefined解析。传递数据或处理错误没有任何作用;实际上,如果if (false)并非总是如此,那么在尝试获取ReferenceError标识符的值时,代码会因err而失败。

如果你想编写一个将Node风格的回调API转换为启用promise的API的函数,那就相当简单了。您假设回调是函数在其参数列表中所期望的最后一个,并且它使用通常的err, data参数调用回调:

const promisify = func => (...args) => new Promise((resolve, reject) => {
    func(...args, (err, data) => {
        if (err) {
            reject(err instanceof Error ? err : new Error(err));
        } else {
            resolve(data);
        }
    });
});

它返回一个函数,当调用它时,将调用原始文件传递其所有参数以及最后的回调,并返回一个promise。当回调被调用时,它假定它采用通常的err, data格式并拒绝承诺,如果err是真实的,否则解决它。它确保拒绝是Error(我的偏好总是使用Error throwreject;您的风格可能会有所不同。)

用法:

const readFileP = promisify(fs.readFile);

然后你想在哪里使用结果:

readFileP("filename", "utf-8")
    .then(data => { /* ... */ })
    .catch(err => { /* ... */ });

然而,如果您进行搜索,那么有一些功能丰富的库可以为您提供更大的灵活性,并且也会进行测试。