得到承诺的回应

Get response with promise

我正在尝试从 API 查询中获取值 returned,但在我所做的所有方法中,它要么是 returns 未定义,要么是 [对象承诺]。我已经尝试了几种解决方案,但仍然没有找到有效的方法。下面是我制作的最后一段代码,看看它是否有效,但还是没有成功。

function generateLink(link) {
  const url = 'https://api.rebrandly.com/v1/links';
  const options = {
    method: 'POST',
    uri: url,
    headers: {'Content-Type': 'application/json', apikey: 'xxxxxxxxxxxxxxxxxxxxx'},
    body: JSON.stringify({destination: link})
  };
  return requestPromise(options).then(response => {
      if ( response.statusCode === 200 ) {
          return response.body
      }
      return Promise.reject(response.statusCode)
  })

}
...
bot.onText(/\/offers (.+)/, function onEchoText(msg, match) {
  console.log(match[1]);
  if (isNaN(match[1])) {
    bot.sendMessage(msg.from.id, 'Enter a valid number! \nExample: /offers 5');
  } else {
    client.execute('aliexpress.affiliate.product.query', {
      'app_signature': 'defualt',
      'category_ids': '701,702,200001081,200001388,200001385,200386159,100000616,100001205,5090301',
      'target_currency': 'USD',
      'target_language': 'EN',
      'tracking_id': 'defualt',
      'ship_to_country': 'US',
    }, function (error, response) {
      var code = response.resp_result.resp_code;
      var mesage = response.resp_result.resp_msg;
      if (code === 200) {
        var i;
        var temCupom = [];
        var link = [];
        var itemList = response.resp_result.result.products.product;
        for (i = 0; i < match[1]; i++) {
          temCupom[i] = itemList[i].promo_code_info ? " <b>There's a coupon!</b>: " + itemList[i].promo_code_info.promo_code : "";
          (async () => { 
            link[i] = generateLink(itemList[i].promotion_link).then(body => { return body.shortUrl })
          })();
          bot.sendPhoto(msg.chat.id, itemList[i].product_main_image_url, {
            caption: "❤ <b>Promotion</b> ❤\n" +
              " <b>Price</b>: " + Number(itemList[i].target_sale_price).toLocaleString('en-us', { style: 'currency', currency: 'USD' }) + "\n" +
              " <b>Link</b>: " + link[i] + "\n" +
              temCupom[i],
          });
        }
      }
      else {
        bot.sendMessage(msg.from.id, 'Deu errado! ' + mesage);
      }
    })
  }

});

link[i]需要return用API

生成的链接

选项 1(async/await):

if (code === 200) {
  var i;
  var link = [];
  var itemList = response.resp_result.result.products.product;
  for (i = 0; i < match[1]; i++) {
    link[i] = await generateLink(itemList[i].promotion_link).then(body => { return JSON.parse(body).shortUrl })
  }
}

选项 2(有承诺):

if (code === 200) {
  var link = [];
  var itemList = response.resp_result.result.products.product;
  for (let i = 0; i < match[1]; i++) {
    generateLink(itemList[i].promotion_link).then(body => { link[i] = JSON.parse(body).shortUrl })
  }
}

选项 3(Promise.all 采用并行模式的所有 URL):

if (code === 200) {
  const itemList = response.resp_result.result.products.product;
  const requests = itemList.slice(0, match[1])
    .map(item => generateLink(item.promotion_link).then(body => JSON.parse(body).shortUrl));

  const links = await Promise.all(requests);
}

===============================

已更新:

毕竟,我们意识到body是一个字符串,有必要做JSON.parse

您需要在 then 块中分配结果。

你可以做一些简单的改变,比如把link[i] = result放到then块中,但是有一些问题,比如i的值是一样的。此外,如果您希望在 for 循环之后填充值,您会注意到它们尚未填充。您需要等到它们全部解决(伪造下面的超时)。

function generateLink(link) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(Math.random())
    }, 1)
  })
}

if (200 === 200) {
  var i;
  var link = [];
  var MAX = 10;

  for (i = 0; i < MAX; i++) {
    generateLink('‍♂️').then(result => {
      link[i] = result; // no bueno - since i will be 10 when this is resolved
    })
  }
  console.log(link) // still not resolved

  setTimeout(() => {
    console.log(link) // ‍♂️ [undefined * 9, value] 
  }, 10)
  
}

// async version (note use of `async`)
(async function(){
  var MAX = 10;
  var link = []
  for (i = 0; i < MAX; i++) {
    link[i] = await generateLink('‍♂️')
  }
  console.log(link)// 
})()

因此您可以增加更多的复杂性以使其工作,但如果您能支持它,async/await 可能是可行的方法。

for (i = 0; i < match[1]; i++) {
  link[i] = await generateLink(itemList[i].promotion_link).then((body) => {
    return body.shortUrl;
  });
}

此外,如果您使用 await,promise 将按顺序执行,您可能不希望这样。并行解析速度更快,但如果您有太多网络请求需要限制它们,您也可能 运行 遇到问题,因此 async await 可能工作得更好)