在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ Promise的結(jié)果是一個(gè)數(shù)組,如何再去調(diào)用一個(gè)Promise,返回最終的組合的

Promise的結(jié)果是一個(gè)數(shù)組,如何再去調(diào)用一個(gè)Promise,返回最終的組合的結(jié)果?

我在寫一個(gè)后臺(tái),封裝了兩個(gè)方法去查詢數(shù)據(jù)庫,它們的返回都是Promise,調(diào)用它們都有正確的結(jié)果。

function list(req, res, next) {
    let start = req.query.start;
    let count = req.query.count;
    exchangeDb.queryList(start, count).then(results => {
        res.json(results)
    }).catch(err => {
        throw err;
    });
}


function load(req, res, next, name) {
    let limit = req.query.limit;
    exchangeDb.queryVolume(name, limit).then(results => {
        req.results = util.convert(results);
        return next();
    }).catch(err => {
        throw err;
    });
}

第一個(gè)返回的是列表,第二個(gè)是返回詳情。我想把它們合為一個(gè)方法,嘗試這樣做:

function list(req, res, next) {
    let start = req.query.start;
    let count = req.query.count;
    exchangeDb.queryList(start, count).then(results => {
        results.forEach((index,element) => {
            exchangeDb.queryVolume(element.name,50).then(volume => {
                element.volume = volume;
                results[index] = element;
            })
        });
        res.json(results)
    }).catch(err => {
        throw err;
    });
}

顯然,它不能工作,我被這個(gè)問題深深的困擾了,如果是鏈?zhǔn)降腜romise,then().then()看上去也不能解決這個(gè)問題,請大家?guī)兔匆幌?,謝謝。

回答
編輯回答
愛是癌

你的目的是在所有queryVolume都返回結(jié)果后,再返回json,因此res.json()一定是一個(gè)異步行為。

兩個(gè)方案:
1.在每個(gè)then里面判斷是否全部請求完畢

        results.forEach((index,element) => {
        
            const NOT_FILL = '__not_fill'
            
            // 生成一個(gè)等長數(shù)組,打標(biāo)記
            const jsonResult = new Array(results.length)
            jsonResult.fill(NOT_FILL)
            
            exchangeDb.queryVolume(element.name,50).then(volume => {
                element.volume = volume;
                jsonResult[index] = element;
                
                // 數(shù)組全部有值再返回
                if(!jsonResult.some(element => element === NOT_FILL)){
                    res.json(jsonResult)
                }
            })
        });

2.把循環(huán)queryVolume的過程封裝成一個(gè)新的promise,resolve的條件同1res.json,然后在這個(gè)promise的then方法中返回json

2017年8月7日 02:04
編輯回答
胭脂淚

如果我沒看錯(cuò)的話,你合并之后的函數(shù)應(yīng)該是在res.json(results)這里返回結(jié)果的,很顯然是不能正確返回的(results很可能是queryList的結(jié)果).因?yàn)槟銉?nèi)部queryVolume是一個(gè)耗時(shí)的操作,程序執(zhí)行到res.json(results) 塊時(shí),此時(shí)results值并沒有被改變。

2018年5月20日 03:31
編輯回答
過客

看起來你是想先取集合,再取集合中每個(gè)元素的詳情。這個(gè)時(shí)候,由于取詳情的操作也是異步操作,所以你不能直接用 forEach,通常來說,你有 Promise.all 和連接成隊(duì)列兩種做法。

Promise.all

exchangeDb.queryList(start, count)
  .then(results => {
    return Promise.all(results.map(element => {
      return exchangeDb.queryVolume(element.name, 50);
    }));
  })
  .then(results => {
    console.log(results); // <- 這里應(yīng)該是全部詳情數(shù)據(jù)了
  })
  .catch(err => {
    throw err;
  });

如果并發(fā)壓力大的話,也可以用隊(duì)列:

exchangeDb.queryList(start, count)
  .then(results => {
    const all = [];
    const p = results.reduce((p, element) => {
      return p.then(() => {
        return exchangeDb.queryVolume(element.name, 50)
          .then(detail => {
            all.push(detail);
          });
      });
    }, Promise.resolve());
    return all;
  })
  .then(results => {
    console.log(results); // <- 這里應(yīng)該是全部詳情數(shù)據(jù)了
  })
  .catch(err => {
    throw err;
  });

我之前做過一次講堂:Promise 的 N 種用法,對 Promise 的講解比較詳細(xì),尤其介紹過幾種隊(duì)列的方式,建議你看一下。

2017年7月23日 07:14