【问题标题】:NodeJS Elasticsearch search returns promise instead of valuesNodeJS Elasticsearch 搜索返回承诺而不是值
【发布时间】:2019-08-31 15:29:08
【问题描述】:

我在我的 Node 服务器中向 Elasticsearch 发出了一个请求。这是完美的工作,除了我总是得到一个返回的承诺而不是结果。

当我控制台记录结果时,它们看起来很完美,但当我返回它们时,我要么一无所获,要么得到承诺。

谁能告诉我从 Elasticsearch 检索和处理数据的正确方法?

我正在使用带有 Node 服务器和官方 Elasticsearch 包的 VueJS。

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

编辑: 正如建议的那样,我尝试了两种代码,都没有工作。我更改了自己的代码,现在它返回一个“未定义”给我。

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

将返回“未定义”给我。我将我的功能更改为:

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

    });
}

什么时候做

let test = getNewTest(client);

它给我一个承诺。

【问题讨论】:

    标签: node.js vue.js elasticsearch


    【解决方案1】:
    (async () => {
    
    let tests = await getNewTest(client);
    console.log(tests);
    })();
    

    您正在调用 db,因此主线程变得空闲并开始执行下一行。代码需要等到promise解决后再执行下一行。

    或者如果你不想使用异步等待,你可以使用下面的这段代码 -

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

    【讨论】:

    • 感谢您的评论!我试过了,但不幸的是我仍然收到“未定义”。我稍后会发布我的代码作为参考。
    • 我改了主帖
    • 不需要使用 let test = getNewTest(client); ,您已经在使用 getNewTest(client).then(function (response) { console.log(response); });
    【解决方案2】:

    函数 getNewTest 将始终返回 undefined,因为您没有明确返回任何内容。

    即使你这样做了:

    function getNewTest(client)
    {
        return client.search({
            index: 'myIndex',
        }).then(function(resp) {
    
            return resp.hits.hits;
    
        }, function(err) {
    
            console.trace(err.message);
    
        });
    }
    

    它将返回一个承诺。

    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);
    当我们调用一个返回承诺(异步工作)的函数时,执行不会等待承诺解决它继续执行其他代码,这就是为什么 const result = test() 不会有结果的承诺。 正如您在代码 sn-p 中看到的那样,promise 的结果将仅在 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');

    你可以使用 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);

    这就是异步的工作方式,你不能返回一个承诺并期望立即收到结果,你可以访问 then 句柄中的结果或像我一样使用 await。

    【讨论】:

    • 感谢您的评论!我试过了,但不幸的是我仍然收到“未定义”。我稍后会发布我的代码作为参考。
    • 我改了主帖
    • 我把答案编辑得更清楚了,希望对你有帮助。
    【解决方案3】:

    当你这样做时:

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

    意思是:

    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
    }
    

    请记住,在 javascript 中,如果您不返回任何内容,则函数的结果是未定义的。我猜你打算做的是:

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

    由于.search() 已经返回了一个 Promise(或类似 Promise 的对象),因此您无需等待它。上面的代码完全一样:

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

    但是,这仍然不允许您执行let test = getNewTest(client)没有任何事情可以让这成为可能。这简直是​​不可能。要获得getNewTest() 的结果,可以调用它的.then() 方法或await。换句话说,要么这样做:

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

    或者这样做:

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

    请注意,此机制适用于任何地方。这样做也是不可能

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

    如果你想走这条路,你必须这样做:

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

    没有逃脱。您可以永远直接返回异步值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 2017-11-24
      • 2018-12-22
      • 2017-01-11
      相关资源
      最近更新 更多