【问题标题】:Promise which executes http.get returns as "pending"执行 http.get 的 Promise 返回“待处理”
【发布时间】:2019-06-27 09:38:05
【问题描述】:

我构建了一系列承诺。一些承诺需要在解决之前进行 http.get() 。其他人没有这个就解决了。我将所有承诺推送到一个数组,然后进行迭代。包括 http.get() 在内的承诺仍在等待中。

我试过做promise.all。我尝试用resolve(200) 替换http.get()。这总是执行承诺。

const https = require('https');
const http = require('http');
let promises = [];

exports.RegisterHTTPDependency = function(url, name, severity) {
  let promise = [];
  let pr = GeneratePromise(url);
  promise.push(pr, name, severity)
  promises.push(promise)
}

exports.Check = function() {
  let results = {};
  for (let i = 0; i < promises.length; i++) {
    const check = promises[i];
    console.log('promise: ', check[0]) // this returns "Promise { <pending> }" or 20, 
    // depending on if the resolve(20) is included in GeneratePromise
  }
}

let GeneratePromise = function(url){
    return new Promise(function(resolve, reject) {
      // resolve(20) // if I include this code, it returns 20
      http.get(url, (resp) => {
        let data = '';
        resp.on('data', (chunk) => {
          data += chunk;
        });
        resp.on('end', () => {
          resolve(resp.statusCode); // this promise does come back <pending>
        });
      }).on("error", (err) => {
        reject(err);
      });
    });
}

值 20 是一个返回值。我希望 resp.statusCode 也成为返回值,而不是挂起。

【问题讨论】:

  • console.log(resp) 得到什么?
  • resp.statusCode 打印 200

标签: node.js promise


【解决方案1】:

由于来自GeneratePromise(),它确实返回了200。你得到一个挂起的原因是当你调用GeneratePromise()函数时,这个函数被调用的地方没有等待promise解决。

简而言之,一个承诺可以有 3 个阶段(pendingfulfilledrejected)。当您输出承诺时,它仍然处于等待状态(尚未resolvedrejected

您可以做的是使用asyncawait 关键字来指示程序阻止执行直到promise 解决,将promise 从pending 阶段变为fulfiled

exports.RegisterHTTPDependency = async function(url, name, severity) {
  let promise = [];
  let pr = await GeneratePromise(url);
  promise.push(pr, name, severity)
  promises.push(promise)
}

【讨论】:

  • 那么get 请求何时真正被解雇?我看到这是可行的,但我需要在运行 Check 函数之前暂停 3 秒,该函数会迭代承诺。如果我不暂停,则不会注册任何承诺。看起来这并没有真正暂停或使一切同步。
  • 建议的修改只会使RegisterHTTPDependency()函数内部的代码同步。但是,如果您以非阻塞方式在RegisterHTTPDependency() 之后立即调用Check(),则RegisterHTTPDependency() 的结果尚未解析。
  • 解决问题的最简单方法是在调用检查之前将RegisterHTTPDependency() 转换为异步函数和await,但重构代码结构应该是更好的解决方案。目前,RegisterHTTPDependency() 创建一个副作用,Check() 检查产生的副作用。最好不要让它们使用副作用来操作。
  • 这很有意义。感谢您的帮助。
  • @bravinator932421 欢迎您。如果答案解决了您的问题,请将答案标记为正确,谢谢。
【解决方案2】:

我认为,如果您有一系列承诺,那么“等待”它们解决的正确方法是使用 Promise.all()。

Promise.all(promisesArray)
  .then(result => {
    // will execute when every promise has been fulfilled
    // result is an array of the values returned by your promises.
  })

https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/Promise/all

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-20
    • 1970-01-01
    • 2018-08-01
    • 1970-01-01
    • 2021-11-01
    • 2020-12-18
    • 2018-09-25
    相关资源
    最近更新 更多