【问题标题】:Promise returns wrong valuePromise 返回错误的值
【发布时间】:2018-07-01 14:01:41
【问题描述】:

在我的代码中,我尝试为 json 变量赋值以在之后返回它(因为我无法从 anon. 函数返回它)。

由于我的函数是异步的,因为它发送请求(也许有人知道如何使它同步?我不打算让它异步),我在请求之前添加了await (https.get)。

我一直试图从 Promise 中获取价值,但它始终是 undefined,即使我已经等待异步函数。

这是一个代码:

async function get_users() {
    const https = require('https');
    var token = '...';
    var json = undefined;

    await https.get('...', (resp) => {
        let data = '';

        resp.on('data', (chunk) => {
            data += chunk;
        });

        resp.on('end', () => {
            json = JSON.parse(data)['response']['items'];
        });
    }).on("error", (err) => {
        console.log("Error: " + err.message);
    });

    return json;
}

get_users().then(function(result) {
    console.log(result);
});

【问题讨论】:

  • 我搜索了一下,不认为https.get 会返回一个承诺。 await 不会等待请求完成。
  • 问题是json 在我返回时是未定义的。什么原因?
  • stackoverflow.com/questions/14220321/… 是问题所在 - 您的 await 将在当前执行环境完成其任务后完成,而不是在请求完成时完成。
  • 那我该怎么办?

标签: javascript asynchronous scope es6-promise synchronous


【解决方案1】:

在调用end事件时返回一个Promiseresolve它,否则在发生错误的情况下返回reject它:

async function get_users() {
  const https = require('https');
  const token = '...';

  return new Promise((resolve, reject) => {
    https.get('...', resp => {
      let data = '';

      resp.on('data', chunk => {
        data += chunk;
      });

      resp.on('end', () => {
        let json;

        try {
          json = JSON.parse(data)['response']['items'];          
        } catch (e) {
          reject(e);
        };
        resolve(json);
      });
    }).on("error", err => reject(err));
  });
}

get_users().then(result => console.log(result));

【讨论】:

  • data 不能被解析为 JSON 时,这会爆炸。您应该只在结束回调中执行resolve(data);,并在promise then 回调中或在await 之后进行任何处理,以便正确处理异常。
  • @Bergi,谢谢!如果您想在get_users() 函数中处理data,您认为在这种情况下最好的方法是什么?
  • return new Promise(…).then(data => JSON.parse(data)['response']['items']);const data = await new Promise(…); return JSON.parse(data)['response']['items'];
【解决方案2】:

请参考我下面的代码。我也遇到了从 Promises 获得响应的问题。但我终于让它工作了。这是代码:

var output;
var rp = require('request-promise-native');
var myJSONObject = {
  "inputs": [{
    "name": "<name>",
    "value": < value >
  }]
};
var orchName = 'TEST05';
postData = JSON.stringify(myJSONObject);
return networkCall(postData, orchName).then((response) => {
  console.log('response is' + response)

}).catch((response) => {
  console.log(`ERROR: ` + response);
});

function networkCall(postData, orchName) {
  return new Promise((resolve, reject) => {
    var options = {
      method: 'post',
      uri: '<URL>',
      body: postData,
      auth: {
        'user': 'usr',
        'pass': 'pwd'
      },
      json: true
    };
    return rp(options)
      .then(body => {
        var response = body;
        resolve(response);
      })
      .catch(err => {
        console.log('FAILED' + err);
        reject(err);
      });
  });
}

这样你的代码可以在同步流中运行。如果返回值为undefined,那么,可能发生的情况是调用函数甚至在被调用函数返回其响应之前就已经执行完毕。但是上面方法会很好用。

【讨论】:

猜你喜欢
  • 2019-07-01
  • 2019-11-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-02
  • 2016-03-11
  • 1970-01-01
  • 2018-03-10
相关资源
最近更新 更多