2016-03-10 3 views
1

У меня есть скрипт nodejs, который получает некоторые данные json, содержащие имена элементов и цены, используя API, а затем проверяет цену этого элемента. Проблема заключается в том, что функция, которая проверяет имя элемента, выполняется до того, как функция, которая записывает прейскурант, заканчивается. Поэтому, если файл прейскуранта не существует, он дает мне «нет такого файла или каталога» для файла прайс-листа. Я искал какое-то время в Интернете, и я нашел что-то в async.series. Я что-то пробовал, но он, похоже, не работает, потому что результат тот же. Если файл прейскуранта существует, сообщение «Цены обновляются успешно! Lenght: появляется после печати цены товара.Ждать окончания функции (в async.series) не работает должным образом

function getPrices() { 
    console.log("URL requested: ", API_URL) 

    restling.get(API_URL).then(function(result) { 
     var JSON_Data = result.data 

     if (JSON_Data.status == "success") { 
      console.log("Prices updated successfully! Lenght: "+JSON_Data.prices.length) 
     } else { 
      console.log(JSON_Data) 
      console.log("An error ocurred during updating prices!") 
      return 
     } 

     fs.writeFileSync("prices/pricelist.txt", JSON.stringify(JSON_Data.prices)) 
    }) 
} 

function getItemPrice(item) { 
    var file = JSON.parse(fs.readFileSync("prices/pricelist.txt")) 

    for (var i = 0; i < file.length; i++) { 
     if (file[i].item_name == item) { 
      return file[i].price 
     } 
    } 
} 

function getItem() { 
    var item1 = getItemPrice('Sword'); 
    console.log(item1); 
} 

async.series([ 
    function(callback){ 
     getPrices(); 
     callback(); 
    }, 
    function(callback){ 
     getItem(); 
     callback(); 
    } 
]); 

EDIT: Я пытался что-то другое, но проблема остается такой же

async.series([ 
    function(callback){ 
     getPrices(); 
     callback(); 
    }, 
    function(callback){ 
     getItem(); 
     callback(); 
    } 
], function(error){ 
    if (error) { 
     console.log(error); 
    } 
}); 

async.waterfall([ 
    function(callback){ 
     getPrices(); 
     callback(); 
    }, 
    function(arg1, callback){ 
     getItem(); 
     callback(); 
    }, 
], function (error) { 
    if (error) { 
     console.log(error); 
    } 
}); 

ответ

1

Ммм, я думаю, что не так много смысла писать ответ в файле для чтения позже, так как вы можете напрямую использовать ответ, чтобы найти элемент, но это должно сработать.

function getPrices(callback) { 

    restling.get(API_URL).then(function(result) { 
    var JSON_Data = result.data 

    if (JSON_Data.status == "success") { 
     console.log("Prices updated successfully! Lenght: " + JSON_Data.prices.length) 
    } else { 
     console.log(JSON_Data) 
     console.log("An error ocurred during updating prices!") 
     return 
    } 

    fs.writeFileSync("prices/pricelist.txt", JSON.stringify(JSON_Data.prices)) 
    callback(null, null); 
    }); 
} 


function getItemPrice(item) { 
    var file = JSON.parse(fs.readFileSync("prices/pricelist.txt")) 

    for (var i = 0; i < file.length; i++) { 
    if (file[i].item_name == item) { 
     return file[i].price 
    } 
    } 
} 


function getItem(callback) { 
    var item1 = getItemPrice('Sword'); 
    callback(null, item1); 
} 


async.series([ 
    getPrices, 
    getItem 
], 
function(err, result) { 
    if (err) { 
    console.log(err); 
    return; 
    } 
    console.log("result", result); 
}); 

Я думаю, что обещает подход, основанный на манипулировании и ответ непосредственно вместо записи/чтения сформировать файл, будет легче понять.

function getPrices(url) { 
    return new Promise(function(resolve) { 
    reslint.get(url).then(function(result) { 
     var data = result.data; 
     if(data.status === "success") { 
      console.log(
      "Prices updated successfully! Lenght: ", 
      data.prices.length 
     ); 
      return resolve(data.prices); 
     } 
     else { 
      throw new Error("An error ocurred during updating prices!"); 
     } 
     }) 
     .catch(function(ex) { 
     throw ex; 
     }); 
    }); 
} 


function getItemPrice(item, items) { 
    for (var i = 0; i < items.length; i++) { 
    if (items[i].item_name == item) { 
     return items[i].price 
    } 
    } 
} 


getPrices("some/url/which/return/prices") 
    .then(function(prices) { 
    console.log(getItemPrice("Sword", prices)); 
    }) 
    .catch(function(err) { 
    console.log("some error -->", err); 
    }); 
+0

Спасибо, сейчас работает. Дело в том, что если API не ответит в данный момент, произойдет ошибка. Поэтому я хочу, чтобы они хранились на всякий случай. – DaNy3LL

+0

@ DaNy3LL sry, что вы имеете в виду, с api не отвечает в данный момент ?, вы имеете в виду вызов reslint.get? –

+0

Я имею в виду, если веб-сайт, имеющий API, по какой-то причине – DaNy3LL

0

Если я не ошибаюсь, не серии ожидают окончательного обратного вызова.

async.series([ 
    function(callback){ 
     getPrices(); 
     callback(); 
    }, 
    function(callback){ 
     getItem(); 
     callback(); 
    } 
], 
function(error, [callback array]){ 
}); 

Если массив обратных вызовов будет содержать результат, возвращаемый из массива функций. Может быть, попробуйте async.waterfall?

+0

Я устал делать что-то подобное, но проблема такая же (см. Мое редактирование выше). На странице [git] (https://github.com/caolan/async) говорится, что обратный вызов является необязательным. – DaNy3LL

+0

Почему бы не разместить содержимое функций в функциях водопада и вместо того, чтобы помещать данные в файл и загружать его снова, просто передайте его на следующий обратный вызов. – MAhsan

Смежные вопросы