简体   繁体   English

NodeJS Elasticsearch搜索返回promise而不是值

[英]NodeJS Elasticsearch search returns promise instead of values

I made a request inside my Node server to Elasticsearch. 我在我的Node服务器中向Elasticsearch发出了请求。 This is working perfect, except that I always get a promise returned instead of the results. 这是完美的,除了我总是得到一个承诺返回而不是结果。

When I console log the results they look perfect, but when I return them I either get nothing or a promise. 当我在控制台上记录结果时,它们看起来很完美,但是当我归还它们时,我要么得不到任何要求。

Can someone tell me the proper way to retrieve, and handle the data from Elasticsearch? 有人可以告诉我正确的方法来检索和处理来自Elasticsearch的数据吗?

I am using VueJS with a Node server and the official Elasticsearch package. 我正在使用VueJS与Node服务器和官方Elasticsearch包。

    function getNewTest(client)
    {
        client.search({
            index: 'myIndex',
        }).then(function(resp) {

            return resp.hits.hits;

        }, function(err) {

            console.trace(err.message);

        });
    }

    let tests = getNewTest(client);
    console.log(tests);

    # Output: Promise { <pending> }

EDIT: As suggested I tried both codes, both didnt work. 编辑:根据建议我尝试了两个代码,两个都没有工作。 I changed my own code, now it returns an "undefined" to me. 我改变了自己的代码,现在它向我返回一个“未定义”。

getNewTest(client).then(function (response) {
           console.log(response);
        });

will return "undefined" to me. 将返回“undefined”给我。 I changed my function to this: 我改变了我的功能:

async function getNewTest(client)
{
    await client.search({
        index: 'myIndex',
    }).then(function(resp) {

        console.log(resp.hits.hits, 'returned');
        return resp.hits.hits;

    }, function(err) {

        console.trace(err.message);

    });
}

When I would do 当我愿意的时候

let test = getNewTest(client);

it returns a promise to me. 它向我回复了一个承诺。

(async () => {

let tests = await getNewTest(client);
console.log(tests);
})();

You are making a db call, so the main thread becomes free and start executing the next line. 您正在进行数据库调用,因此主线程变为空闲并开始执行下一行。 The code needs to wait till the promise is resolved and then execute the next line. 代码需要等到promise被解决然后执行下一行。

Or if you dont want to use async await, you can use this code below - 或者,如果您不想使用异步等待,您可以使用下面的代码 -

async function getNewTest(client) {
    client.search({
        index: 'myIndex',
    }).then(function (resp) {

        return resp.hits.hits;

    }, function (err) {

        console.trace(err.message);

    });
}


getNewTest(client).then(result => {
    console.log(result);
});

Function getNewTest will alway return undefined because you do not explicitly return anything. 函数getNewTest始终返回undefined,因为您没有显式返回任何内容。

Even if you did it this way : 即使你这样做了:

function getNewTest(client)
{
    return client.search({
        index: 'myIndex',
    }).then(function(resp) {

        return resp.hits.hits;

    }, function(err) {

        console.trace(err.message);

    });
}

It will return a promise. 它会回报一个承诺。

 const generatePromise = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(1500) }, 500) }) function test () { return generatePromise() .then((data) => console.log('after promise resolved ', data)) .catch((err) => console.log(err)) } console.log('before calling test function'); const result = test() console.log('after calling test function', result instanceof Promise); 
When we call a function that returns a promise (async work) the execution does not wait for the promise to resolve it continue executing other code, that why const result = test() won't have the result of the promise. 当我们调用一个返回promise(异步工作)的函数时,执行不会等待promise的解析继续执行其他代码,这就是为什么const result = test()不会有promise的结果。 The result of the promise will only be available inside the then handler as you can see in the code snippet. 承诺的结果只能在then处理程序中使用,您可以在代码片段中看到。

 const generatePromise = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(1500) }, 500) }) function test () { return generatePromise() } console.log('before calling test function'); test() .then((data) => console.log('after promise resolved ', data)) .catch((err) => console.log(err)) console.log('after calling test function'); 

You can achieve the required using async & await: 您可以使用async和await实现所需的:

 const generatePromise = () => new Promise((resolve, reject) => { setTimeout(() => { resolve(1500) }, 500) }) // async function always returns promise even if you did't explicitly do async function test () { const data = await generatePromise(); // you can access resolved data here console.log('after promise resolved ', data); return data; } // first without then console.log('before calling test function'); // you can't access it here unless you use then // test().then(data => console.log(data)); const result = test(); console.log('after calling test function', result instanceof Promise); 

This is how asynchronous works you can't return a promise and expect to receive the results instantly you can access the results inside the then handles or use await as I did. 这是异步工作的方式,你无法返回一个承诺,并期望立即收到结果你可以访问当时句柄内的结果或使用等待我。

When you do this: 当你这样做:

async function getNewTest(client)
{
    await client.search({
        index: 'myIndex',
    }).then(function(resp) {

        console.log(resp.hits.hits, 'returned');
        return resp.hits.hits;

    }, function(err) {

        console.trace(err.message);

    });
}

it means this: 它意味着:

async function getNewTest(client)
{
    await client.search({
        index: 'myIndex',
    }).then(function(resp) {

        console.log(resp.hits.hits, 'returned');
        return resp.hits.hits;

    }, function(err) {

        console.trace(err.message);

    });

    return undefined; // you are deliberately returning undefined
}

Remember that in javascript if you don't return anything the result of the function is undefined. 请记住,在javascript中如果不返回任何内容,则函数的结果是未定义的。 I'm guessing what you intend to do is: 我猜你打算做的是:

async function getNewTest(client)
{
    return await client.search({ // NOTE THIS LINE
        index: 'myIndex',
    }).then(function(resp) {

        console.log(resp.hits.hits, 'returned');
        return resp.hits.hits;

    }, function(err) {

        console.trace(err.message);

    });
}

Since .search() already returns a Promise (or promise-like object) you don't need to await for it. 由于.search()已经返回Promise(或类似promise的对象),因此您无需等待它。 The code above is exactly the same as: 上面的代码完全相同:

function getNewTest(client)
{
    return client.search({ // NOTE THIS RETURN
        index: 'myIndex',
    }).then(function(resp) {

        console.log(resp.hits.hits, 'returned');
        return resp.hits.hits;

    }, function(err) {

        console.trace(err.message);

    });
}

But still, this does not allow you to do let test = getNewTest(client) . 但是,这仍然不允许你let test = getNewTest(client) Nothing will ever make this possible. 什么都不会使这成为可能。 It is simply impossible . 这根本不可能 To get the result of getNewTest() either call it's .then() method or await for it. 要获取getNewTest()的结果,请调用它的.then()方法或await它。 In other words, either do this: 换句话说,要么这样做:

getNewTest(client).then(function(test) { /*continue logic here*/ })

or do this: 或者这样做:

async function foo () {
    let test = await getNewTest(client);

    /*continue logic here*/
}

foo();

Note that this mechanism applies everywhere. 请注意,此机制适用于所有地方 It is also impossible to do this: 这也是不可能的

async function foo () {
    let test = await getNewTest(client);
    return test;
}

let test = foo();

You must instead do this if you want to go this route: 如果你想走这条路,你必须这样做:

async function foo () {
    let test = await getNewTest(client);
    return test;
}

async function bar () {
    let test = await foo();
    /*continue logic here*/
}

There is no escape. 跑不了的。 You can never directly return an asynchronous value. 永远不能直接返回异步值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM