如何将变量和 API 响应传递给下一个承诺 (.then)

How to pass a variable AND an API response to the next promise (.then)

我利用第一个承诺 "crypto.model.find()" 从数据库中存储一个 "symbols" ( symbol[] ) 的数组,并获取一些我将用来创建 URL 的 ID向 API 发出请求 >>> axios.get(url)

在第二个承诺中,我收到了 API 的答复,但我无权访问我的数组符号 []。

现阶段我需要两者,但我不知道该怎么做。

我读到过 returning 数组并将其传递到 promises 链中,但在这种情况下,我认为我不能使用这样的数组:return [ axios.get(url), 符号[] ]

// getting coins description in my DB with Mongoose  
cryptoModel.find()                                                      
.then ( docsCrypto => {
        let coingeckoIDsRequest = '';                                   
        let symbol = [];  

// loop on the response from the DB
        docsCrypto.forEach( (eachCrypto) => {                           
// Filling the array of symbols from the DB
            symbol.push( eachCrypto.symbol )                            
// creating a chunk of the HTTPS API URL request with the IDs from the DB
            coingeckoIDsRequest += eachCrypto.coingecko_id + '%2C'      
        })

// URL creation
        let url = 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&ids=' +
            coingeckoIDsRequest.substr(0, coingeckoIDsRequest.length-3) +
            '&order=market_cap_desc&per_page=100&page=1&sparkline=false&price_change_percentage=24h%2C7d%2C30d%2C200d'      

// returning the API data   
        return axios.get(url)                                           
})
// !!! >>>>  I want to get to the next line with the data from the API AND the array "symbol[]" 
.then (res => console.log(res)) 
// if error > console.log       
.catch (err => console.log(err))

尝试在查找函数之外声明符号数组。

您可以使用 Promise.resolve(your_variable) 创建一个立即解析为变量值的新承诺。

然后可以用Promise.all组合起来

我在这个例子中使用 setTimeout 而不是真正的 axios

let variable = "value of a variable";

const axios = {
  get: () => new Promise(
    res => setTimeout(() => res('axios response'), 1000)
  )
}

Promise.all([
  axios.get(),
  Promise.resolve(variable)
]).then(
  resolved => console.log(resolved)
);

只需使用Promise.all() 聚合您希望传递的两个成员。一个是Promise,一个是Array,没关系。

明智地使用 Array.prototype.map() 可以避免很多麻烦。

cryptoModel.find()
.then(docsCrypto => {
    let symbols = docsCrypto.map(eachCrypto => eachCrypto.symbol);
    let url = 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=eur&ids=' +
        docsCrypto.map(eachCrypto => eachCrypto.coingecko_id).join('%2C') +
        '&order=market_cap_desc&per_page=100&page=1&sparkline=false&price_change_percentage=24h%2C7d%2C30d%2C200d';
    return Promise.all([axios.get(url), symbols]);
})

在链的下一阶段,destructuring提供了一种访问两个结果的便捷方式。

.then(([axiosResult, symbols]) => {
    console.log(axiosResult);
    console.log(symbols);
});