扔进一个承诺崩溃服务器

时间:2016-05-23 07:04:34

标签: javascript promise ecmascript-6 babeljs

这里有一段代码应该按照我的知识完美运行,但是会崩溃服务器

注意:我正在使用带有babel的ES6

const getDataFromCouchBase = function (siteId) {
    return new Promise((resolve, reject) => {
        const cluster = new couchbase.Cluster('127.0.0.1:8091'),
            bucket = cluster.openBucket(bucketName, (err) => {
                console.log("err: ", err);
                if (err) {
                    throw err;
                    //reject(err);
                }

                // Retrieve a document
                bucket.get(`site::${siteId}`, (err, result) => {
                    console.log("err: ", err);
                    console.log("result: ", result);
                    if (err) {
                        throw err;
                        //reject(err);
                    }
                    resolve(result.value);
                });
            });
    });
}

这是我用thencatch

调用此函数
getDataFromCouchBase(siteId).then((site) => {
    console.log(site);
}).catch((err) => {
    console.log(err);
});

如果存在错误的bucketName或存储桶中没有的文档,则会导致服务器崩溃而不是由catch块处理的抛出错误

1 个答案:

答案 0 :(得分:3)

承诺“处理”抛出的唯一时间是new Promise回调内的同步代码或thencatch回调中的同步代码。我不知道CouchBase,但我认为openBucket回调是异步的,所以它完全在承诺处理之外。

您需要已注释掉的代码:reject(err);,而不是throw err;。无论如何,它更符合你正在做的事情。

以下是使用setTimeout模拟异步性的代码的类比:

const getDataFromCouchBase = function () {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            throw new Error("asynchronous throw");
        }, 0);
    });
}
getDataFromCouchBase()
    .then(r => {
        console.log("result:", r);
    })
    .catch(e => {
        console.log("error:", e.message);
    });

Live on Babel's REPL

请注意throw是如何(并且不能)转换为拒绝的。 (它显示在实际的Web控制台中[不是Babel的伪控制台,是devtools中的实际控制台]。)

如果throw 同步,它可以(并且被)转换为拒绝:

const getDataFromCouchBase = function () {
    return new Promise((resolve, reject) => {
        throw new Error("synchronous throw");
    });
}
getDataFromCouchBase()
    .then(r => {
        console.log("result:", r);
    })
    .catch(e => {
        console.log("error:", e.message);
    });

Live copy on Babel's REPL

请注意throw如何转换为拒绝。但在你的情况下,我确信回调是异步调用的。