回调以确保异步api请求完成

时间:2018-04-10 21:13:42

标签: javascript node.js asynchronous

我知道这个主题上已经有成千上万的主题已经存在,而且我已经研究了这个问题几天了,但是我还是不明白怎么做应用我已经完成的案例。

我从这样的API调用开始:

const getReleaseUrl = (discogsId) => { 
  db.getRelease(discogsId, (err, data) => {
    return data.uri
  }) 
}

console.log(getReleaseUrl("53130"));
// => undefined

如何确保我的应用首先收到数据,阻止undefined返回?我是否需要以某种方式确保db首先使用我的客户端ID定义并连接到远程数据库?我是否需要编写一个以某种方式捕获undefined结果的函数并一直反复运行API调用,直到结果不同为止?设置超时似乎不是一个好的永久解决方案。我尝试编写像这样的Promise链并得到TypeError: db.getRelease(...).then is not a function错误:

const getReleaseUrl = (discogsId) => { 
  db.getRelease(discogsId, (err, data) => {
    return data
  })
  .then((data) => {
    return data.uri
  })   
}

console.log(getReleaseUrl("53130"));

5 个答案:

答案 0 :(得分:2)

您使用此编码的方式,除了undefined之外,您的控制台消息无法返回任何内容。

对于初学者,您的方法没有return语句。当然,回调有一个return语句,但这并不重要。没有退货声明,没有任何记录。使用您定义的方法,您可以做的最好的事情是在回调中放置控制台消息

const getReleaseUrl = (discogsId) => { 
  db.getRelease(discogsId, (err, data) => {
    console.log(data.uri);
    return data.uri
  }) 
}

getReleaseUrl("53130");

更好的选择是重写函数以接受回调作为参数:

const getReleaseUrl = (discogsId, callback) => { 
  db.getRelease(discogsId, callback);
}

getRelaseUrl("53130", (err, data) => {
  console.log(data.uri);
});

在这里,您将从主函数中移除有关如何处理返回数据的逻辑,从而为您提供更大的灵活性。它还确保在数据准备好之前不会调用日志消息。

答案 1 :(得分:1)

查看db.getRelease之前添加的回报:

使用node.js util宣传db.getRelease

var util = require('util');
var getRelease = util.promisify(db.getRelease);

返回整个数据:

const getReleaseUrl = (discogsId) => {       
  return getRelease(discogsId); 
}

或返回特定的一个:

const getReleaseUrl = (discogsId) => {       
      return getRelease(discogsId)
             .then(function(data){ 
                  return data.uri;
             }); 
}        

答案 2 :(得分:1)

您可以通过回调或使用Promise。 让我们来看看承诺选项:

bool Train::isValid() const
{
    Car* curr;
    Car* temp;
    Car* Fin;
    Car* MVP;
    bool result;

    //Setting current node to the head node's next, head node will always be a locomotive, hence not involved.
    curr = m_head->getNext();

    //If any of the condition returns false, the loop should break.
    while(curr != NULL)
    {
        temp = curr->getNext();       //Setting first trail node to the current node's next
        if(temp != NULL)
        {
        Fin = temp->getNext();             //Setting second trail node to the first trail node's next

        //Condition for combustible car being next to a oxidizer car
        if((curr->getCargo()==3)&&(temp->getCargo()==2)||(curr->getCargo()==2)&&(temp->getCargo()==3))           
        {
            result = false;break;
        }
        else
            result = true;
        if(Fin != NULL)
        {
        MVP = Fin->getNext();              //Setting third trail node to the second trail node's next

        //Condition for three combustible cars being in a row
        if((curr->getCargo()==3)&&(temp->getCargo()==3)&&(Fin->getCargo()==3))
        {
                result = false;break;
        }

        //Condition for a radioactive car being next to a biological car
        else if((curr->getCargo()==4)&&(temp->getCargo()==0)&&(Fin->getCargo()==4))
        {
                result = false;break;
        }
        else
            result = true;
        if(MVP != NULL)
        {

            //Condition for five biological cars being in a row
        if((curr->getCargo()==0)&&(temp->getCargo()==0)&&(Fin->getCargo()==0)&&(MVP->getCargo()==0)&&((Fin->getNext())->getCargo()==0))
        {
                result = false;break;
        }
        else
            result = true;
        }
        }
        }

        //moving current node to its next
        curr = curr->getNext();
    }
    return result;
}

问题在于,正如您所说,对db.getRelease的调用是异步的,因此getReleaseUrl不会返回任何内容。 看看Pop-A-Stash对回调选项的回答。

答案 3 :(得分:0)

看起来db.getRelease已经接受了回调,因此您可以处理成功和错误。

你的getReleaseUrl函数不会返回任何内容。从箭头函数中删除花括号或添加return语句。

答案 4 :(得分:0)

使用承诺

var promise1 = new Promise(function(resolve, reject) {
resolve('Success!');
});

promise1.then(function(value) {
console.log(value);
// expected output: "Success!"
});

按照此处的步骤操作: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then