0

您好,我是异步调用的新手,希望您能帮助我。

我有一个 .then 链,我想在链的中间调用一个返回承诺的函数,但发生在我身上的是,链不等待它获得承诺函数的结果,而是继续而不等待

var User = require('../models/user_model');
var mapbox = require('./helper/request_api_mapbox');

findOne_mapbox: (req, res) => {
  User.findById(req.params.id)
        .then(user => {
            
            ...
            return user.address;
        })
         .then(function (adress_to_mapbox) 
            {
                // mapbox.connect_mapbox returns a promise
                mapbox.connect_mapbox(adress_to_mapbox)
                .then(mapbox_coordinates => {
                    //inside this console.log is not read it
                    console.log("2 then mapbox_coordinates ", mapbox_coordinates)
                    return Promise.resolve(body);
                })   
                           
            })
             .then(  mapbox_coordinates  => {

                // in this console.log mapbox_coordinates returns undefined
                console.log("last promise mapbox_coordinates", 
                mapbox_coordinates)

                // I want to return mapbox_coordinates
                return res.status(200).send({
                    "response": "I only receive this string " 
                });
            })

}

承诺功能是:

'use strict'

const rp = require('request-promise');
const access_token_mapbox = 'bla bla bla private';

function connect_mapbox(adress_to_mapbox) {
    return new Promise((resolve, reject) => {  
        
        var options = {
            method: 'GET',
            uri: 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + adress_to_mapbox + '.json?access_token=' + access_token_mapbox,                 
            json: true // Automatically stringifies the body to JSON
        };
    
        rp(options)
        .then(body => {
            if (body.hasOwnProperty('errcode') && body.errcode != 0) {
            return Promise.reject(body);
            }
            console.log("inside connect_mapbox function on mapbox_model 2", body)
            
            return Promise.resolve(body);
        })
        .catch(err => {
            debug(err);
            return Promise.reject(err);
        })
        
    })  
}   

module.exports = { connect_mapbox };

在 promise 函数中,我可以在我的 console.log 中看到它可以正确调用 api 并且响应体是好的。

4

1 回答 1

0

我从编程开始,我通过以下方式解决了问题,虽然我不知道它是否最正确

我通过将 connect_mapbox 承诺函数转换为 async await 并将 .then 链转换为 async await 来解决它,如下所示:

'use strict'

const rp = require('request-promise');
const access_token_mapbox = 'bla bla bla private';

async function connect_mapbox(adress_to_mapbox) {

    try {

        var options = {
            method: 'GET',
            uri: 'https://api.mapbox.com/geocoding/v5/mapbox.places/' + adress_to_mapbox + '.json?access_token=' + access_token_mapbox,                 
            json: true // Automatically stringifies the body to JSON
        };

        let response = await rp(options);

        console.log("inside connect_mapbox function on mapbox_model", response)

        if (response.hasOwnProperty('errcode') && body.errcode != 0) {
            return Promise.reject(response);
        }

        return Promise.resolve(response);

    }catch(error) {
        return Promise.reject(error);
    }
}

module.exports = { connect_mapbox };

而 .then 链就像

var User = require('../models/user_model');
var mapbox = require('./helper/request_api_mapbox');

findOne_mapbox: (req, res) => {
  User.findById(req.params.id)
        .then(user => {
            
            ...
            return user.address;
        })
         .then(async function (adress_to_mapbox) 
            {
                
                console.log("adress_to_mapbox thit could be deleted", adress_to_mapbox)
                    
                let mapbox_response = await mapbox.connect_mapbox(adress_to_mapbox)
                   
                console.log("async mapbox_response", mapbox_response) 

                return res.status(200).send({
                    mapbox_response 
                });
            })
             ...

}
于 2020-07-01T19:55:53.940 回答