【问题标题】:Code Always Executes after response is sent to the browser响应发送到浏览器后始终执行代码
【发布时间】:2019-11-17 23:44:58
【问题描述】:

这是我有一个问题的代码,如果我没有在 asyncCall 函数中设置超时,那么响应会在异步代码完成之前发送,因此我没有从 onlineBooksImages() 函数,但在下面的代码中包含超时

  setTimeout(() => {


    if (onlineBook) {

        res.status(200).render("showBooks",
            {
                result: result,
                favourites: favourites,
                user: user,
                book: onlineBook

            });
    } 



}, 5000);

延迟了响应的发送,因此我得到了图像我如何编写下面的代码以消除比使用异步代码更快的加载更长的超时

var boos = []
var boos2 = []
var boos3 = []
var foo = {}
var foo2 = {}
var foo3 = {}

const onlineBook= await Books2.findById(req.params.id);
const Ebook = await Ebooks.findById(req.params.id);

 function onlineBooksImages() {
    return new Promise(resolve => {
        setTimeout(() => {

            let temporaryVar = []
            onlineBook.allimages.forEach(element => {
                gfs.files.findOne({ _id: element }, (err, file) => {
                    if (!file || file.length === 0) {
                        return res.status(404).json({
                            err: "No file exist"
                        });
                    }
                    var u = []
                    u.push(onlineBook._id)
                    var img = []
                    img.push(file)
                    user.push(file)
                    foo3[u] = temporaryVar;
                    //console.log(user.length);
                });
            });
            boos3.push(foo3)

            resolve(boos3);
        }, 100);
    });
} 
  async function asyncCall() {
    console.log('calling');
    if (onlineBook) {
        var result = await onlineBooksImages();
    } else if (Ebook) {
        var result2 = await someOtherFunction();//notImportant

    } else {
        return res.status(404).render('error', { user });
    }
    setTimeout(() => {


        if (onlineBook) {

            res.status(200).render("showBooks",
                {
                    result: result,
                    favourites: favourites,
                    user: user,
                    book: onlineBook

                });
        } 



    }, 5000);

}

【问题讨论】:

  • 您在 .forEach 中执行异步操作 - 这永远不会起作用 - 您需要承诺 gfs.files.findOne 调用(除非它已经可以返回 Promise)并使用常规 for/for ...of/for...in 循环与 async/await
  • 你知道我该怎么做吗......
  • 快速提问 ... (!file || file.length === 0) 是否应该取消整个过程并只返回 404 状态,即使另一个迭代可能会找到(或之前已经找到)file
  • 哦,这个var u = [] u.push(onlineBook._id) foo3[u] = temporaryVar; 是一种奇怪的做法foo3(onlineBook._id) = temporaryVar;
  • (!file || file.length === 0) 是的,但现在想起来你提到它是一个错误的选择

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


【解决方案1】:

在答案之前......这里有一些有趣的代码

  this code looks wrong on many levels

  var u = [];
  u.push(onlineBook._id);
  // snip
  foo3[u] = temporaryVar;

现在,让我们说onlineBook._id === "abc"

因此u === ['abc']

所以foo3[u]foo3[u.toString()] 相同......这将是foo3['abc']

那么为什么不只是foo3[onlineBook._id] = temporaryVar;

但即使这样看起来也很奇怪,因为foo3 中的每个属性都会引用同一个数组

例如如果图书 ID 是 'abc'、'def' 和 'ghi',那么 foo3.abcfoo3.deffoo3.ghi 将是完全相同的空数组!

无论如何,回答一下,虽然我仍然对您的“全局” boos* 和 foo* 变量感到困惑 - 但让我们解决您遇到的问题:

function async onlineBooksImages() {
  let temporaryVar = [];
  for (let element of onlineBook.allimages) {
    try {
      const file = await new Promise((resolve, reject) => {
        gfs.files.findOne({_id: element}, (err, file) => {
            if (err) {
                return reject(err);
            }
            temporaryVar.push(file);
            resolve(file);
        })
      });
      if (!file || file.length === 0) {
        return reject();
      }
      foo3[onlineBook._id] = temporaryVar;

    } catch(e) {
        // do nothing but catch the error
    }
  }
  if (Object.keys(foo3).length) {
    boos3.push(foo3);
    return boos3;
  } else {
    // reject if there were no images in any of allimages
    throw({status: 400, err: "No file exist"});
  }
}

async function asyncCall() {
  console.log('calling');
  try {
    if (onlineBook) {
      var result = await onlineBooksImages();
    } else if (Ebook) {
      var result2 = await someOtherFunction();//notImportant
    } else {
      return res.status(404).render('error', { user });
    }
    if (onlineBook) {
      res.status(200).render("showBooks", {
        result: result,
        favourites: favourites,
        user: user,
        book: onlineBook
      });
    } 
  } catch(e) {
      if (e.status && e.err) {
        res.status(e.status).json({
          err: e.err
        });
      }
  }
}

【讨论】:

  • 是的,这解决了异步问题关于处理承诺和异步代码的任何建议谢谢
猜你喜欢
  • 1970-01-01
  • 2011-03-23
  • 2011-05-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-23
  • 2013-07-03
  • 1970-01-01
相关资源
最近更新 更多