使用async / await从回调返回对象

时间:2020-01-15 21:13:29

标签: javascript node.js asynchronous callback async-await

我无法用this question的答案来解决此问题,因为代码存在差异。

我想从回调中返回一个对象。当我运行以下代码时,for layer_name in targets[0:1]: print(f'generating dataset {layer_name}') submodel = tf.keras.models.Model([model.inputs[0]], [model.get_layer(layer_name).output]) batch = submodel.output.get_shape()[-1] input_img_data = np.random.random((batch, 224, 224, 3)) input_img_data = (input_img_data - 0.5) * 20 + 128. input_img_data = tf.Variable(tf.cast(input_img_data, tf.float32)) input_img_list = tf.split(input_img_data, batch, axis=0) zero_init = tf.zeros_initializer() loss_value = [tf.Variable(0, dtype=tf.float32) for i in range(batch)] #print(loss_value) for _ in range(epochs): #print(tf.split(input_img_data, batch, axis=0)) with tf.GradientTape() as tape: outputs = tf.dtypes.cast(submodel(preprocess_input(input_img_data)), tf.float32) for i in range(batch): ph = tf.Variable(initial_value=zero_init(shape=(224, 224, 3)),dtype=tf.float32) ph = tf.reduce_mean(outputs[:,:,:,i]) #print(loss_value) loss_value[i].assign(ph) grads = tape.gradient(loss_value, tf.split(input_img_data, batch, axis=0)) print(grads) # normalized_grads = grads / (tf.sqrt(tf.reduce_mean(tf.square(grads))) + 1e-5) # input_img_data.assign_add(normalized_grads * step_size) for i in range(batch): image = input_img_data.numpy()[i,:,:,:].astype(np.uint8) p = mp.Process(target=Image.fromarray(image).save(fp=f'./synth_sets/vgg16_cifar10_test/{layer_name}_{i}.jpg')) p.start() 对象的日志看起来像预期的那样。它似乎是正确的JSON对象,其中包含我想要来自服务器的响应:名称,电子邮件,网站等。

但是body对象似乎包含有关请求本身的信息,而不是响应对象。

如何返回result对象,以便可以从body变量访问它?

result

这就是我要从const request = require('request'); // npm i request -s module.exports = async config => { ... const result = await request.get( url, options, ( error, response, body, ) => { console.log( 'body', body, ); // I want the other log to look like this log. return body; } ); console.log( 'result', result, ); // I want this log to look like the above log. // In other words, I want the below line to be the name, email, website JSON object // contained in the body return result; } 中获得的东西。 console.log('body',body,);

result

这实际上是我从body { "name": "foo", "email": "foo@example.com", "website": "www.example.com", ... } 那里得到的。

console.log('result',result,);
result

2 个答案:

答案 0 :(得分:4)

使用Promise

const result = await new Promise((resolve) => {
  request.get(url, options, (error, response, body) => {
      console.log( 'body', body );
      resolve(body);
    });
});

编辑:

或者您可以安装https://github.com/request/request-promise

答案 1 :(得分:2)

request.get()不返回承诺,因此await上没有任何用处。如果我每次回答这个问题时都有一个镍,那我就会有很多镍。 await没有魔法。它所做的就是等待诺言。如果您没有兑现承诺,它将无能为力。

您可能不知道,但是request模块及其派生版本位于maintenance mode中(没有新功能,仅修复了错误)。您可以使用request-promise模块然后摆脱回调,也可以切换到正在积极开发的较新模块,例如got模块。那是我的建议:

const got = require('got');

module.exports = async config => {
  ...

  const result = await got(url, options);

  console.log( 'result', result ); // I want this log to look like the above log.
  // In other words, I want the below line to be the name, email, website JSON object
  // contained in the body
  return result;
}

而且,我希望您认识到所有async函数都返回一个Promise,因此此函数的调用者必须对返回的Promise使用await.then()才能获得结果超出了预期。


如果您想使用request库,则可以使用request-promise获取该库的已承诺版本:

const rp = require('request-promise');

module.exports = async config => {
  ...

  const result = await rp(url, options);

  console.log( 'result', result ); // I want this log to look like the above log.
  // In other words, I want the below line to be the name, email, website JSON object
  // contained in the body
  return result;
}