首页 > 解决方案 > 响应发送到浏览器后始终执行代码

问题描述

这是我有一个问题的代码,如果我没有在 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);

}

标签: javascriptnode.jsasynchronouspromiseasync-await

解决方案


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

  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.def并且foo3.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
        });
      }
  }
}

推荐阅读