承诺.then()链:第二个。然后在第一个之前运行? o.0

时间:2019-09-29 21:46:06

标签: javascript file asynchronous promise async-await

我正试图从.then结构中的blob数据创建一个新的File对象,然后在第二个.then之后,读取该文件的信息。

但是第二个然后在第一个结束之前运行,因此文件对象尚未填充。

这是正常行为吗?我是否应该创建一个异步函数,先在第一个函数中调用,然后确保第二个函数在之后被严格调用?

    private static Connection igniteConnection;
    private static Statement sql;
    private static ResultSet rs;

    public static void main(String[] args) throws Exception
    {
        Class.forName("org.apache.ignite.IgniteJdbcThinDriver");

        IgniteConfiguration conf = new IgniteConfiguration();
        Ignite ignite = Ignition.start(conf);

        igniteConnection = DriverManager.getConnection("jdbc:ignite:thin://localhost:3606/test;user=root;password=root");

        sql = igniteConnection.createStatement();

        sql.executeUpdate("CREATE TABLE Employee (" +
        " id LONG PRIMARY KEY, name VARCHAR(30), country VARCHAR(30))");

        PreparedStatement sql = igniteConnection.prepareStatement("INSERT INTO Employee (id, name, country) VALUES (?, ?, ?)");

        sql.setLong(1, 1);
        sql.setString(2, "James");
        sql.setString(3, "EEUU");
        sql.executeUpdate();

        rs = sql.executeQuery("SELECT e.name, e.country FROM Employee");

        while(rs.next()){
            String name = rs.getString(1);
            String country = rs.getString(2);
            System.out.println(name+"\t"+country);
        }

        ignite.close();
        igniteConnection.close();
        rs.close();
    }
}

控制台显示了我

let output = {file: {}, file_infos: {}}, image = FileAPI.Image(src_file); await Promise.all(Object.keys(parameters).map(async (parameter_name) => { // Pass file threw all modifiers (resizing, rotation, overlaying) try { image = await FileMethods[parameter_name](image, parameters[parameter_name]); return image; } catch(err) { console.log(err); }; })) .then((output_image) => { output_image[0].toBlob((blob) => { output.file = new File([blob], src_file.name); // Need this to be fullfilled before step2 console.log('step1'); }); }) .then(() => { console.log('step2'); FileAPI.getInfo(output.file, (err/**String*/, infos/**Object*/) => { if( !err ){ output.file_infos = infos; } else { console.log("this is triggered because output.file isn't filled yet"); } }) }); // console.log(output); return output;

感谢帮助:)

3 个答案:

答案 0 :(得分:2)

两个.then中的两个异步函数不会返回Promise,因此首先它们必须被“承诺”,因为您已经在使用async/await,所以请不要使用promise {{1 }}链

.then

关于

的注释
const image = FileAPI.Image(src_file);
const output_image = await Promise.all(Object.keys(parameters).map(async(parameter_name) => {
    try {
        image = await FileMethods[parameter_name](image, parameters[parameter_name]);
        return image;
    } catch (err) {
        console.log(err);
    };
}));
const file = await new Promise((resolve, reject) => output_image[0].toBlob((blob) => 
    resolve(new File([blob], src_file.name))
));
const file_infos = await new Promise((resolve, reject) => FileAPI.getInfo(file, (err, file_infos) => {
    if (!err) {
        resolve(file_infos);
    } else {
        reject("this is triggered because output.file isn't filled yet");
    }
));
return {file, file_infos};

您实际上是在做const output_image = await Promise.all(Object.keys(parameters).map(async(parameter_name) => { try { image = await FileMethods[parameter_name](image, parameters[parameter_name]); return image; } catch (err) { console.log(err); }; })); -因此,在这种情况下,您实际上不需要异步/等待模式,只需在.map中返回Promise

return await FileMethods[parameter_name](image, parameters[parameter_name])

或者,更好(在我看来)

const output_image = await Promise.all(Object.keys(parameters).map((parameter_name) => 
    FileMethods[parameter_name](image, parameters[parameter_name]);
));

  

或者,使用Promise .then链,而无需异步/等待

const output_image = await Promise.all(Object.entries(parameters).map((p_name, p_value) =>
    FileMethods[p_name](image, p_value)
));

答案 1 :(得分:1)

toBlob可能是异步的。将第一个.then更改为此:

.then((output_image) => {
  return new Promise((resolve) => output_image[0].toBlob((blob) => {
    output.file = new File([blob], src_file.name); // Need this to be fullfilled before step2
    console.log('step1');
    resolve();
  }));
})

答案 2 :(得分:1)

.toBlob()立即返回,因为它使用了异步回调模式。

您要返回的诺言是在工作完成时解决的。因此,您可以执行以下操作:

.then((output_image) => {
    return new Promise((res, rej) => {
      output_image[0].toBlob((blob) => {
        output.file = new File([blob], src_file.name); // Need this to be fullfilled before step2
        console.log('step1');
        res();
      });
    });
  })